diff --git a/WickedEngine/shaders/raytraceCS.hlsl b/WickedEngine/shaders/raytraceCS.hlsl index 333f1f849..c5a0a6009 100644 --- a/WickedEngine/shaders/raytraceCS.hlsl +++ b/WickedEngine/shaders/raytraceCS.hlsl @@ -54,6 +54,13 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) { ray.Direction = normalize(ray.Direction); + float4 additive_dist = float4(0, 0, 0, FLT_MAX); + +#ifdef RTAPI + RayQuery< + RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES + > q; + uint flags = 0; #ifdef RAY_BACKFACE_CULLING flags |= RAY_FLAG_CULL_BACK_FACING_TRIANGLES; @@ -63,13 +70,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) flags |= RAY_FLAG_FORCE_OPAQUE; } -#ifdef RTAPI - RayQuery< - RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES - > q; q.TraceRayInline( scene_acceleration_structure, // RaytracingAccelerationStructure AccelerationStructure - flags, // uint RayFlags + flags, // uint RayFlags xTraceUserData.y, // uint InstanceInclusionMask ray // RayDesc Ray ); @@ -88,12 +91,22 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) if (!surface.load(prim, q.CandidateTriangleBarycentrics())) break; - [branch] - if (surface.opacity - rng.next_float() >= 0) + if (surface.material.options & SHADERMATERIAL_OPTION_BIT_ADDITIVE) + { + additive_dist.xyz += max(0, energy * surface.emissiveColor); + additive_dist.w = min(additive_dist.w, q.CandidateTriangleRayT()); + } + else if (surface.opacity - rng.next_float() >= 0) { q.CommitNonOpaqueTriangleHit(); } } + + if (additive_dist.w <= q.CommittedRayT()) + { + result += max(0, energy * additive_dist.xyz); + } + if (q.CommittedStatus() != COMMITTED_TRIANGLE_HIT) #else RayHit hit = TraceRay_Closest(ray, xTraceUserData.y, rng, groupIndex); @@ -159,6 +172,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) surface.V = -ray.Direction; surface.update(); + result += max(0, energy * surface.emissiveColor); + raycone = raycone.propagate(surface.roughnessBRDF, surface.hit_depth); if (bounce == 0) @@ -173,8 +188,6 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) break; } - result += max(0, energy * surface.emissiveColor); - if (!surface.material.IsUnlit()) { // Light sampling: diff --git a/WickedEngine/shaders/rtreflectionCS.hlsl b/WickedEngine/shaders/rtreflectionCS.hlsl index a996e18d8..c7b774f17 100644 --- a/WickedEngine/shaders/rtreflectionCS.hlsl +++ b/WickedEngine/shaders/rtreflectionCS.hlsl @@ -93,6 +93,8 @@ void main(uint2 DTid : SV_DispatchThreadID) RayCone raycone = RayCone::from_spread_angle(pixel_cone_spread_angle_from_image_height(postprocess.resolution.y)); raycone = raycone.propagate(sqr(max(minraycone, roughness)), lineardepth * GetCamera().z_far); + float4 additive_dist = float4(0, 0, 0, FLT_MAX); + RayQuery< RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES > q; @@ -119,12 +121,22 @@ void main(uint2 DTid : SV_DispatchThreadID) float alphatest = clamp(blue_noise(DTid.xy, q.CandidateTriangleRayT()).r, 0, 0.99); - [branch] - if (surface.opacity - alphatest >= 0) + if (surface.material.options & SHADERMATERIAL_OPTION_BIT_ADDITIVE) + { + additive_dist.xyz += max(0, surface.emissiveColor); + additive_dist.w = min(additive_dist.w, q.CandidateTriangleRayT()); + } + else if (surface.opacity - alphatest >= 0) { q.CommitNonOpaqueTriangleHit(); } } + + if (additive_dist.w <= q.CommittedRayT()) + { + payload.data.xyz += max(0, additive_dist.xyz); + } + if (q.CommittedStatus() != COMMITTED_TRIANGLE_HIT) { // miss: @@ -209,7 +221,9 @@ void main(uint2 DTid : SV_DispatchThreadID) lighting.indirect.diffuse = ddgi_sample_irradiance(surface.P, surface.N); } - ApplyLighting(surface, lighting, payload.data); + float4 color = 0; + ApplyLighting(surface, lighting, color); + payload.data.xyz += color.rgb; } payload.data.w = q.CommittedRayT(); } diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index aa9420d95..ba36c9b0d 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -3798,6 +3798,8 @@ namespace wi::scene inst.uid = entity; inst.layerMask = hair.layerMask; inst.geometryOffset = (uint)geometryAllocation; + inst.emissive = wi::math::Pack_R11G11B10_FLOAT(XMFLOAT3(1, 1, 1)); + inst.color = wi::math::CompressColor(XMFLOAT4(1, 1, 1, 1)); const size_t instanceIndex = objects.GetCount() + args.jobIndex; std::memcpy(instanceArrayMapped + instanceIndex, &inst, sizeof(inst)); @@ -3878,6 +3880,8 @@ namespace wi::scene inst.uid = entity; inst.layerMask = emitter.layerMask; inst.geometryOffset = (uint)geometryAllocation; + inst.emissive = wi::math::Pack_R11G11B10_FLOAT(XMFLOAT3(1, 1, 1)); + inst.color = wi::math::CompressColor(XMFLOAT4(1, 1, 1, 1)); const size_t instanceIndex = objects.GetCount() + hairs.GetCount() + args.jobIndex; std::memcpy(instanceArrayMapped + instanceIndex, &inst, sizeof(inst)); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 9c5316916..4b5ac5bd7 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 60; // minor bug fixes, alterations, refactors, updates - const int revision = 38; + const int revision = 39; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);