diff --git a/README.md b/README.md index d8fabd3ae..31afcbd8d 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,9 @@ Sponza scene with voxel GI enabled: Damaged Helmet GLTF sample model: ![Sponza](https://turanszkij.files.wordpress.com/2019/03/damagedhelmet.png) +Path tracing in the living room: +![LivingRoom](https://turanszkij.files.wordpress.com/2019/09/livingroom.jpg) + City scene with a light map, model from Michael Gallie: ![City](https://turanszkij.files.wordpress.com/2019/01/city1.png) diff --git a/WickedEngine/ShaderInterop_BVH.h b/WickedEngine/ShaderInterop_BVH.h index c67896717..76606bfbf 100644 --- a/WickedEngine/ShaderInterop_BVH.h +++ b/WickedEngine/ShaderInterop_BVH.h @@ -6,12 +6,12 @@ static const uint BVH_BUILDER_GROUPSIZE = 64; CBUFFER(BVHCB, CBSLOT_RENDERER_BVH) { - float4x4 xTraceBVHWorld; - float4 xTraceBVHInstanceColor; - uint xTraceBVHMaterialOffset; - uint xTraceBVHMeshTriangleOffset; - uint xTraceBVHMeshTriangleCount; - uint xTraceBVHMeshVertexPOSStride; + float4x4 xBVHWorld; + float4 xBVHInstanceColor; + uint xBVHMaterialOffset; + uint xBVHMeshTriangleOffset; + uint xBVHMeshTriangleCount; + uint xBVHMeshVertexPOSStride; }; diff --git a/WickedEngine/bvh_primitivesCS.hlsl b/WickedEngine/bvh_primitivesCS.hlsl index 30ca1d788..d17fddf26 100644 --- a/WickedEngine/bvh_primitivesCS.hlsl +++ b/WickedEngine/bvh_primitivesCS.hlsl @@ -24,8 +24,8 @@ RWSTRUCTUREDBUFFER(primitiveMortonBuffer, float, 3); // morton buffer is float b void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) { const uint tri = DTid.x; - const uint primitiveID = xTraceBVHMeshTriangleOffset + tri; - const bool activeThread = tri < xTraceBVHMeshTriangleCount; + const uint primitiveID = xBVHMeshTriangleOffset + tri; + const bool activeThread = tri < xBVHMeshTriangleCount; if (activeThread) { @@ -35,9 +35,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) uint i2 = meshIndexBuffer[tri * 3 + 1]; // load vertices of triangle from vertex buffer: - float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xTraceBVHMeshVertexPOSStride)); - float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xTraceBVHMeshVertexPOSStride)); - float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xTraceBVHMeshVertexPOSStride)); + float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xBVHMeshVertexPOSStride)); + float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xBVHMeshVertexPOSStride)); + float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xBVHMeshVertexPOSStride)); uint nor_u = asuint(pos_nor0.w); float3 nor0 = unpack_unitvector(nor_u); @@ -51,8 +51,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) // Compute triangle parameters: - float4x4 WORLD = xTraceBVHWorld; - const uint materialIndex = xTraceBVHMaterialOffset + subsetIndex; + float4x4 WORLD = xBVHWorld; + const uint materialIndex = xBVHMaterialOffset + subsetIndex; ShaderMaterial material = materialBuffer[materialIndex]; float3 v0 = mul(WORLD, float4(pos_nor0.xyz, 1)).xyz; @@ -65,7 +65,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) float4 u1 = float4(meshVertexBuffer_UV0[i1] * material.texMulAdd.xy + material.texMulAdd.zw, meshVertexBuffer_UV1[i1]); float4 u2 = float4(meshVertexBuffer_UV0[i2] * material.texMulAdd.xy + material.texMulAdd.zw, meshVertexBuffer_UV1[i2]); - const float4 color = xTraceBVHInstanceColor * material.baseColor; + const float4 color = xBVHInstanceColor * material.baseColor; float4 c0 = color; float4 c1 = color; float4 c2 = color; diff --git a/WickedEngine/raytrace_closesthitCS.hlsl b/WickedEngine/raytrace_closesthitCS.hlsl index b71206b78..f18ed69d1 100644 --- a/WickedEngine/raytrace_closesthitCS.hlsl +++ b/WickedEngine/raytrace_closesthitCS.hlsl @@ -55,7 +55,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex ) if (ray_active) { - RayHit hit = TraceScene(ray); + RayHit hit = TraceRay_Closest(ray); if (hit.distance >= INFINITE_RAYHIT - 1) { float3 envColor; diff --git a/WickedEngine/raytrace_debugbvhPS.hlsl b/WickedEngine/raytrace_debugbvhPS.hlsl index 596481ee4..36a7cb016 100644 --- a/WickedEngine/raytrace_debugbvhPS.hlsl +++ b/WickedEngine/raytrace_debugbvhPS.hlsl @@ -5,7 +5,7 @@ float4 main(float4 pos : SV_POSITION, float2 clipspace : TEXCOORD) : SV_Target { Ray ray = CreateCameraRay(clipspace); - uint hitCount = TraceBVH(ray); + uint hitCount = TraceRay_DebugBVH(ray); if (hitCount == 0xFFFFFFFF) { diff --git a/WickedEngine/raytrace_shadeCS.hlsl b/WickedEngine/raytrace_shadeCS.hlsl index d50be3b5d..095bf3b18 100644 --- a/WickedEngine/raytrace_shadeCS.hlsl +++ b/WickedEngine/raytrace_shadeCS.hlsl @@ -268,7 +268,7 @@ void main(uint3 DTid : SV_DispatchThreadID) newRay.direction = L + sampling_offset * 0.025f; newRay.direction_rcp = rcp(newRay.direction); newRay.energy = 0; - bool hit = TraceSceneANY(newRay, dist); + bool hit = TraceRay_Any(newRay, dist); bounceResult += (hit ? 0 : NdotL) * (lighting.direct.diffuse + lighting.direct.specular); } } diff --git a/WickedEngine/raytracingHF.hlsli b/WickedEngine/raytracingHF.hlsli index c15142d6e..59c19db31 100644 --- a/WickedEngine/raytracingHF.hlsli +++ b/WickedEngine/raytracingHF.hlsli @@ -239,15 +239,14 @@ inline bool IntersectTriangleANY(in Ray ray, in float maxDistance, in BVHPrimiti inline bool IntersectNode(in Ray ray, in BVHNode box, in float primitive_best_distance) { - float t[6]; - t[0] = (box.min.x - ray.origin.x) * ray.direction_rcp.x; - t[1] = (box.max.x - ray.origin.x) * ray.direction_rcp.x; - t[2] = (box.min.y - ray.origin.y) * ray.direction_rcp.y; - t[3] = (box.max.y - ray.origin.y) * ray.direction_rcp.y; - t[4] = (box.min.z - ray.origin.z) * ray.direction_rcp.z; - t[5] = (box.max.z - ray.origin.z) * ray.direction_rcp.z; - const float tmin = max(max(min(t[0], t[1]), min(t[2], t[3])), min(t[4], t[5])); // close intersection point's distance on ray - const float tmax = min(min(max(t[0], t[1]), max(t[2], t[3])), max(t[4], t[5])); // far intersection point's distance on ray + const float t0 = (box.min.x - ray.origin.x) * ray.direction_rcp.x; + const float t1 = (box.max.x - ray.origin.x) * ray.direction_rcp.x; + const float t2 = (box.min.y - ray.origin.y) * ray.direction_rcp.y; + const float t3 = (box.max.y - ray.origin.y) * ray.direction_rcp.y; + const float t4 = (box.min.z - ray.origin.z) * ray.direction_rcp.z; + const float t5 = (box.max.z - ray.origin.z) * ray.direction_rcp.z; + const float tmin = max(max(min(t0, t1), min(t2, t3)), min(t4, t5)); // close intersection point's distance on ray + const float tmax = min(min(max(t0, t1), max(t2, t3)), max(t4, t5)); // far intersection point's distance on ray if (tmax < 0 || tmin > tmax || tmin > primitive_best_distance) // this also checks if a better primitive was already hit or not and skips if yes { @@ -260,15 +259,14 @@ inline bool IntersectNode(in Ray ray, in BVHNode box, in float primitive_best_di } inline bool IntersectNode(in Ray ray, in BVHNode box) { - float t[6]; - t[0] = (box.min.x - ray.origin.x) * ray.direction_rcp.x; - t[1] = (box.max.x - ray.origin.x) * ray.direction_rcp.x; - t[2] = (box.min.y - ray.origin.y) * ray.direction_rcp.y; - t[3] = (box.max.y - ray.origin.y) * ray.direction_rcp.y; - t[4] = (box.min.z - ray.origin.z) * ray.direction_rcp.z; - t[5] = (box.max.z - ray.origin.z) * ray.direction_rcp.z; - const float tmin = max(max(min(t[0], t[1]), min(t[2], t[3])), min(t[4], t[5])); // close intersection point's distance on ray - const float tmax = min(min(max(t[0], t[1]), max(t[2], t[3])), max(t[4], t[5])); // far intersection point's distance on ray + const float t0 = (box.min.x - ray.origin.x) * ray.direction_rcp.x; + const float t1 = (box.max.x - ray.origin.x) * ray.direction_rcp.x; + const float t2 = (box.min.y - ray.origin.y) * ray.direction_rcp.y; + const float t3 = (box.max.y - ray.origin.y) * ray.direction_rcp.y; + const float t4 = (box.min.z - ray.origin.z) * ray.direction_rcp.z; + const float t5 = (box.max.z - ray.origin.z) * ray.direction_rcp.z; + const float tmin = max(max(min(t0, t1), min(t2, t3)), min(t4, t5)); // close intersection point's distance on ray + const float tmax = min(min(max(t0, t1), max(t2, t3)), max(t4, t5)); // far intersection point's distance on ray return (tmax < 0 || tmin > tmax) ? false : true; } @@ -287,7 +285,7 @@ STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_ONDEMAND5); // Returns the closest hit primitive if any (useful for generic trace). If nothing was hit, then rayHit.distance will be equal to INFINITE_RAYHIT -inline RayHit TraceScene(Ray ray) +inline RayHit TraceRay_Closest(Ray ray) { RayHit bestHit = CreateRayHit(); @@ -342,7 +340,7 @@ inline RayHit TraceScene(Ray ray) } // Returns true immediately if any primitives were hit, flase if nothing was hit (useful for opaque shadows): -inline bool TraceSceneANY(Ray ray, float maxDistance) +inline bool TraceRay_Any(Ray ray, float maxDistance) { bool shadow = false; @@ -402,8 +400,7 @@ inline bool TraceSceneANY(Ray ray, float maxDistance) // Returns number of BVH nodes that were hit (useful for debug): // returns 0xFFFFFFFF when there was a stack overflow -// returns (0xFFFFFFFF - 1) when the exit condition was reached -inline uint TraceBVH(Ray ray) +inline uint TraceRay_DebugBVH(Ray ray) { uint hit_counter = 0; diff --git a/WickedEngine/renderlightmapPS.hlsl b/WickedEngine/renderlightmapPS.hlsl index fb593f031..fbe2b50fe 100644 --- a/WickedEngine/renderlightmapPS.hlsl +++ b/WickedEngine/renderlightmapPS.hlsl @@ -137,14 +137,14 @@ float4 main(Input input) : SV_TARGET newRay.direction = L + sampling_offset * 0.025f; newRay.direction_rcp = rcp(newRay.direction); newRay.energy = 0; - bool hit = TraceSceneANY(newRay, dist); + bool hit = TraceRay_Any(newRay, dist); bounceResult += (hit ? 0 : NdotL) * lighting.direct.diffuse / PI; } } ray.color += max(0, ray.energy * bounceResult); // Sample primary ray (scene materials, sky, etc): - RayHit hit = TraceScene(ray); + RayHit hit = TraceRay_Closest(ray); if (hit.distance >= INFINITE_RAYHIT - 1) { diff --git a/WickedEngine/wiGPUBVH.cpp b/WickedEngine/wiGPUBVH.cpp index cfe8c1257..abb5fdda2 100644 --- a/WickedEngine/wiGPUBVH.cpp +++ b/WickedEngine/wiGPUBVH.cpp @@ -403,16 +403,16 @@ void wiGPUBVH::Build(const Scene& scene, CommandList cmd) const MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); BVHCB cb; - cb.xTraceBVHWorld = object.transform_index >= 0 ? scene.transforms[object.transform_index].world : IDENTITYMATRIX; - cb.xTraceBVHInstanceColor = object.color; - cb.xTraceBVHMaterialOffset = materialCount; - cb.xTraceBVHMeshTriangleOffset = primitiveCount; - cb.xTraceBVHMeshTriangleCount = (uint)mesh.indices.size() / 3; - cb.xTraceBVHMeshVertexPOSStride = sizeof(MeshComponent::Vertex_POS); + cb.xBVHWorld = object.transform_index >= 0 ? scene.transforms[object.transform_index].world : IDENTITYMATRIX; + cb.xBVHInstanceColor = object.color; + cb.xBVHMaterialOffset = materialCount; + cb.xBVHMeshTriangleOffset = primitiveCount; + cb.xBVHMeshTriangleCount = (uint)mesh.indices.size() / 3; + cb.xBVHMeshVertexPOSStride = sizeof(MeshComponent::Vertex_POS); device->UpdateBuffer(&constantBuffer, &cb, cmd); - primitiveCount += cb.xTraceBVHMeshTriangleCount; + primitiveCount += cb.xBVHMeshTriangleCount; device->BindConstantBuffer(CS, &constantBuffer, CB_GETBINDSLOT(BVHCB), cmd); @@ -426,7 +426,7 @@ void wiGPUBVH::Build(const Scene& scene, CommandList cmd) }; device->BindResources(CS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), cmd); - device->Dispatch((cb.xTraceBVHMeshTriangleCount + BVH_BUILDER_GROUPSIZE - 1) / BVH_BUILDER_GROUPSIZE, 1, 1, cmd); + device->Dispatch((cb.xBVHMeshTriangleCount + BVH_BUILDER_GROUPSIZE - 1) / BVH_BUILDER_GROUPSIZE, 1, 1, cmd); for (auto& subset : mesh.subsets) { diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index cbec9e44c..ad8ac23d6 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 28; // minor bug fixes, alterations, refactors, updates - const int revision = 16; + const int revision = 17; long GetVersion()