From e092154aebbb47c68e79353d4668db36333bf09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Wed, 22 Feb 2023 09:02:04 +0100 Subject: [PATCH] area light raytracing fixes --- WickedEngine/shaders/ddgi_raytraceCS.hlsl | 25 +++++------------ WickedEngine/shaders/raytraceCS.hlsl | 2 +- WickedEngine/shaders/renderlightmapPS.hlsl | 25 +++++------------ WickedEngine/shaders/screenspaceshadowCS.hlsl | 28 +++++-------------- WickedEngine/shaders/surfel_raytraceCS.hlsl | 25 +++++------------ WickedEngine/wiVersion.cpp | 2 +- 6 files changed, 30 insertions(+), 77 deletions(-) diff --git a/WickedEngine/shaders/ddgi_raytraceCS.hlsl b/WickedEngine/shaders/ddgi_raytraceCS.hlsl index a39ffa9a4..5fe28af6f 100644 --- a/WickedEngine/shaders/ddgi_raytraceCS.hlsl +++ b/WickedEngine/shaders/ddgi_raytraceCS.hlsl @@ -151,6 +151,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn dist = FLT_MAX; L = light.GetDirection().xyz; + L += sample_hemisphere_cos(L, rng) * light.GetRadius(); NdotL = saturate(dot(L, surface.N)); [branch] @@ -170,6 +171,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn break; case ENTITY_TYPE_POINTLIGHT: { + light.position += light.GetDirection() * (rng.next_float() - 0.5) * light.GetLength(); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -194,6 +197,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn break; case ENTITY_TYPE_SPOTLIGHT: { + float3 Loriginal = normalize(light.position - surface.P); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -209,7 +214,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn [branch] if (NdotL > 0) { - const float spot_factor = dot(L, light.GetDirection()); + const float spot_factor = dot(Loriginal, light.GetDirection()); const float spot_cutoff = light.GetConeAngleCos(); [branch] @@ -233,23 +238,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn newRay.Origin = surface.P; newRay.TMin = 0.001; newRay.TMax = dist; - - newRay.Direction = L; - if (light.GetRadius() > 0) - { - switch (light.GetType()) - { - default: - case ENTITY_TYPE_DIRECTIONALLIGHT: - newRay.Direction += sample_hemisphere_cos(L, rng) * light.GetRadius(); - break; - case ENTITY_TYPE_POINTLIGHT: - case ENTITY_TYPE_SPOTLIGHT: - newRay.Direction = normalize(light.position + sample_hemisphere_cos(L, rng) * light.GetRadius() - surface.P); - break; - } - } - newRay.Direction += max3(surface.sss); + newRay.Direction = L + max3(surface.sss); #ifdef RTAPI q.TraceRayInline( diff --git a/WickedEngine/shaders/raytraceCS.hlsl b/WickedEngine/shaders/raytraceCS.hlsl index d6789e738..9c1d33fc0 100644 --- a/WickedEngine/shaders/raytraceCS.hlsl +++ b/WickedEngine/shaders/raytraceCS.hlsl @@ -232,8 +232,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) break; case ENTITY_TYPE_POINTLIGHT: { - light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); light.position += light.GetDirection() * (rng.next_float() - 0.5) * light.GetLength(); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); diff --git a/WickedEngine/shaders/renderlightmapPS.hlsl b/WickedEngine/shaders/renderlightmapPS.hlsl index 79b49fe19..ba36d6b5c 100644 --- a/WickedEngine/shaders/renderlightmapPS.hlsl +++ b/WickedEngine/shaders/renderlightmapPS.hlsl @@ -66,6 +66,7 @@ float4 main(Input input) : SV_TARGET dist = FLT_MAX; L = light.GetDirection().xyz; + L += sample_hemisphere_cos(L, rng) * light.GetRadius(); NdotL = saturate(dot(L, surface.N)); [branch] @@ -85,6 +86,8 @@ float4 main(Input input) : SV_TARGET break; case ENTITY_TYPE_POINTLIGHT: { + light.position += light.GetDirection() * (rng.next_float() - 0.5) * light.GetLength(); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -110,6 +113,8 @@ float4 main(Input input) : SV_TARGET break; case ENTITY_TYPE_SPOTLIGHT: { + float3 Loriginal = normalize(light.position - surface.P); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -125,7 +130,7 @@ float4 main(Input input) : SV_TARGET [branch] if (NdotL > 0) { - const float spot_factor = dot(L, light.GetDirection()); + const float spot_factor = dot(Loriginal, light.GetDirection()); const float spot_cutoff = light.GetConeAngleCos(); [branch] @@ -150,23 +155,7 @@ float4 main(Input input) : SV_TARGET newRay.Origin = surface.P; newRay.TMin = 0.001; newRay.TMax = dist; - - newRay.Direction = L; - if (light.GetRadius() > 0) - { - switch (light.GetType()) - { - default: - case ENTITY_TYPE_DIRECTIONALLIGHT: - newRay.Direction += sample_hemisphere_cos(L, rng) * light.GetRadius(); - break; - case ENTITY_TYPE_POINTLIGHT: - case ENTITY_TYPE_SPOTLIGHT: - newRay.Direction = normalize(light.position + sample_hemisphere_cos(L, rng) * light.GetRadius() - surface.P); - break; - } - } - newRay.Direction += max3(surface.sss); + newRay.Direction = L + max3(surface.sss); #ifdef RTAPI uint flags = RAY_FLAG_CULL_FRONT_FACING_TRIANGLES; diff --git a/WickedEngine/shaders/screenspaceshadowCS.hlsl b/WickedEngine/shaders/screenspaceshadowCS.hlsl index 58b5704e4..2ad9aa2f2 100644 --- a/WickedEngine/shaders/screenspaceshadowCS.hlsl +++ b/WickedEngine/shaders/screenspaceshadowCS.hlsl @@ -126,6 +126,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : case ENTITY_TYPE_DIRECTIONALLIGHT: { L = normalize(light.GetDirection()); + L += mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(L)) * light.GetRadius(); SurfaceToLight surfaceToLight; surfaceToLight.create(surface, L); @@ -143,10 +144,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : break; case ENTITY_TYPE_POINTLIGHT: { - if (light.GetLength() > 0) - { - light.position = light.position + light.GetDirection() * (blue_noise(DTid.xy).g - 0.5) * light.GetLength(); - } + light.position += light.GetDirection() * (blue_noise(DTid.xy).g - 0.5) * light.GetLength(); + light.position += mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(normalize(light.position - surface.P))) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -172,6 +171,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : break; case ENTITY_TYPE_SPOTLIGHT: { + float3 Loriginal = normalize(light.position - surface.P); + light.position += mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(normalize(light.position - surface.P))) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range2 = light.GetRange() * light.GetRange(); @@ -186,7 +187,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : surfaceToLight.create(surface, L); [branch] - if (any(surfaceToLight.NdotL_sss) && (dot(L, light.GetDirection()) > light.GetConeAngleCos())) + if (any(surfaceToLight.NdotL_sss) && (dot(Loriginal, light.GetDirection()) > light.GetConeAngleCos())) { ray.TMax = dist; } @@ -203,22 +204,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : uint seed = 0; float shadow = 0; - ray.Direction = L; - if (light.GetRadius() > 0) - { - switch (light.GetType()) - { - default: - case ENTITY_TYPE_DIRECTIONALLIGHT: - ray.Direction += mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(L)) * light.GetRadius(); - break; - case ENTITY_TYPE_POINTLIGHT: - case ENTITY_TYPE_SPOTLIGHT: - ray.Direction = normalize(light.position + mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(L)) * light.GetRadius() - P); - break; - } - } - ray.Direction += max3(surface.sss); + ray.Direction = L + max3(surface.sss); #ifdef RTAPI RayQuery< diff --git a/WickedEngine/shaders/surfel_raytraceCS.hlsl b/WickedEngine/shaders/surfel_raytraceCS.hlsl index f7eb10895..57e26bc22 100644 --- a/WickedEngine/shaders/surfel_raytraceCS.hlsl +++ b/WickedEngine/shaders/surfel_raytraceCS.hlsl @@ -143,6 +143,7 @@ void main(uint3 DTid : SV_DispatchThreadID) dist = FLT_MAX; L = light.GetDirection().xyz; + L += sample_hemisphere_cos(L, rng) * light.GetRadius(); NdotL = saturate(dot(L, surface.N)); [branch] @@ -162,6 +163,8 @@ void main(uint3 DTid : SV_DispatchThreadID) break; case ENTITY_TYPE_POINTLIGHT: { + light.position += light.GetDirection() * (rng.next_float() - 0.5) * light.GetLength(); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -187,6 +190,8 @@ void main(uint3 DTid : SV_DispatchThreadID) break; case ENTITY_TYPE_SPOTLIGHT: { + float3 Loriginal = normalize(light.position - surface.P); + light.position += sample_hemisphere_cos(normalize(light.position - surface.P), rng) * light.GetRadius(); L = light.position - surface.P; const float dist2 = dot(L, L); const float range = light.GetRange(); @@ -202,7 +207,7 @@ void main(uint3 DTid : SV_DispatchThreadID) [branch] if (NdotL > 0) { - const float spot_factor = dot(L, light.GetDirection()); + const float spot_factor = dot(Loriginal, light.GetDirection()); const float spot_cutoff = light.GetConeAngleCos(); [branch] @@ -227,23 +232,7 @@ void main(uint3 DTid : SV_DispatchThreadID) newRay.Origin = surface.P; newRay.TMin = 0.001; newRay.TMax = dist; - - newRay.Direction = L; - if (light.GetRadius() > 0) - { - switch (light.GetType()) - { - default: - case ENTITY_TYPE_DIRECTIONALLIGHT: - newRay.Direction += sample_hemisphere_cos(L, rng) * light.GetRadius(); - break; - case ENTITY_TYPE_POINTLIGHT: - case ENTITY_TYPE_SPOTLIGHT: - newRay.Direction = normalize(light.position + sample_hemisphere_cos(L, rng) * light.GetRadius() - surface.P); - break; - } - } - newRay.Direction += max3(surface.sss); + newRay.Direction = L + max3(surface.sss); #ifdef RTAPI q.TraceRayInline( diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 4c3980900..d5ca12485 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 = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 159; + const int revision = 160; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);