From 00ae64b79d5f57df76f8dde82a49040792d589af Mon Sep 17 00:00:00 2001 From: RaveYard Date: Tue, 5 Jul 2022 09:19:52 +0200 Subject: [PATCH] Discard traces via dot product for every light in GPU/CPU --- src/lightmap/cpuraytracer.cpp | 77 ++++++++++++++++--------------- src/lightmap/glsl_rgen_light.h | 82 +++++++++++++++++----------------- 2 files changed, 82 insertions(+), 77 deletions(-) diff --git a/src/lightmap/cpuraytracer.cpp b/src/lightmap/cpuraytracer.cpp index 6c3b2e4..3a26712 100644 --- a/src/lightmap/cpuraytracer.cpp +++ b/src/lightmap/cpuraytracer.cpp @@ -270,50 +270,53 @@ void CPURaytracer::RunLightTrace(CPUTraceState& state) { vec3 dir = normalize(light.Origin - origin); - float distAttenuation = std::max(1.0f - (dist / light.Radius), 0.0f); - float angleAttenuation = 1.0f; - if (surface) + if (!surface || dot(normal, dir) > 0.0) { - angleAttenuation = std::max(dot(normal, dir), 0.0f); - } - float spotAttenuation = 1.0f; - if (light.OuterAngleCos > -1.0f) - { - float cosDir = dot(dir, light.SpotDir); - spotAttenuation = smoothstep(light.OuterAngleCos, light.InnerAngleCos, cosDir); - spotAttenuation = std::max(spotAttenuation, 0.0f); - } - - float attenuation = distAttenuation * angleAttenuation * spotAttenuation; - if (attenuation > 0.0f) - { - float shadowAttenuation = 0.0f; - - if (state.PassType == 0 && surface) + float distAttenuation = std::max(1.0f - (dist / light.Radius), 0.0f); + float angleAttenuation = 1.0f; + if (surface) { - vec3 e0 = normalize(cross(normal, std::abs(normal.x) < std::abs(normal.y) ? vec3(1.0f, 0.0f, 0.0f) : vec3(0.0f, 1.0f, 0.0f))); - vec3 e1 = cross(normal, e0); - e0 = cross(normal, e1); - for (uint32_t i = 0; i < state.SampleCount; i++) + angleAttenuation = std::max(dot(normal, dir), 0.0f); + } + float spotAttenuation = 1.0f; + if (light.OuterAngleCos > -1.0f) + { + float cosDir = dot(dir, light.SpotDir); + spotAttenuation = smoothstep(light.OuterAngleCos, light.InnerAngleCos, cosDir); + spotAttenuation = std::max(spotAttenuation, 0.0f); + } + + float attenuation = distAttenuation * angleAttenuation * spotAttenuation; + if (attenuation > 0.0f) + { + float shadowAttenuation = 0.0f; + + if (state.PassType == 0 && surface) { - vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension); - vec3 origin2 = origin + e0 * offset.x + e1 * offset.y; + vec3 e0 = normalize(cross(normal, std::abs(normal.x) < std::abs(normal.y) ? vec3(1.0f, 0.0f, 0.0f) : vec3(0.0f, 1.0f, 0.0f))); + vec3 e1 = cross(normal, e0); + e0 = cross(normal, e1); + for (uint32_t i = 0; i < state.SampleCount; i++) + { + vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension); + vec3 origin2 = origin + e0 * offset.x + e1 * offset.y; - LevelTraceHit hit = Trace(origin2, light.Origin); - if (hit.fraction == 1.0f) - shadowAttenuation += 1.0f; + LevelTraceHit hit = Trace(origin2, light.Origin); + if (hit.fraction == 1.0f) + shadowAttenuation += 1.0f; + } + shadowAttenuation *= 1.0f / float(state.SampleCount); + } + else + { + LevelTraceHit hit = Trace(origin, light.Origin); + shadowAttenuation = (hit.fraction == 1.0f) ? 1.0f : 0.0f; } - shadowAttenuation *= 1.0f / float(state.SampleCount); - } - else - { - LevelTraceHit hit = Trace(origin, light.Origin); - shadowAttenuation = (hit.fraction == 1.0f) ? 1.0f : 0.0f; - } - attenuation *= shadowAttenuation; + attenuation *= shadowAttenuation; - incoming += light.Color * (attenuation * light.Intensity * incomingAttenuation); + incoming += light.Color * (attenuation * light.Intensity * incomingAttenuation); + } } } } diff --git a/src/lightmap/glsl_rgen_light.h b/src/lightmap/glsl_rgen_light.h index ccbc53b..1f0050b 100644 --- a/src/lightmap/glsl_rgen_light.h +++ b/src/lightmap/glsl_rgen_light.h @@ -93,7 +93,7 @@ void main() const float dist = 32768.0; float attenuation = 0.0; - if (PassType == 0 && surfaceIndex >= 0) + if (PassType == 0 && surfaceIndex >= 0 && dot(normal, SunDir) > 0.0) { vec3 e0 = normalize(cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0))); vec3 e1 = cross(normal, e0); @@ -125,53 +125,55 @@ void main() if (dist > minDistance && dist < light.Radius) { vec3 dir = normalize(light.Origin - origin); - - float distAttenuation = max(1.0 - (dist / light.Radius), 0.0); - float angleAttenuation = 1.0f; - if (surfaceIndex >= 0) + if(surfaceIndex < 0 || dot(normal, dir) > 0.0) { - angleAttenuation = max(dot(normal, dir), 0.0); - } - float spotAttenuation = 1.0; - if (light.OuterAngleCos > -1.0) - { - float cosDir = dot(dir, light.SpotDir); - spotAttenuation = smoothstep(light.OuterAngleCos, light.InnerAngleCos, cosDir); - spotAttenuation = max(spotAttenuation, 0.0); - } - - float attenuation = distAttenuation * angleAttenuation * spotAttenuation; - if (attenuation > 0.0) - { - float shadowAttenuation = 0.0; - - if (PassType == 0 && surfaceIndex >= 0) + float distAttenuation = max(1.0 - (dist / light.Radius), 0.0); + float angleAttenuation = 1.0f; + if (surfaceIndex >= 0) { - vec3 e0 = normalize(cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0))); - vec3 e1 = cross(normal, e0); - e0 = cross(normal, e1); - for (uint i = 0; i < SampleCount; i++) + angleAttenuation = max(dot(normal, dir), 0.0); + } + float spotAttenuation = 1.0; + if (light.OuterAngleCos > -1.0) + { + float cosDir = dot(dir, light.SpotDir); + spotAttenuation = smoothstep(light.OuterAngleCos, light.InnerAngleCos, cosDir); + spotAttenuation = max(spotAttenuation, 0.0); + } + + float attenuation = distAttenuation * angleAttenuation * spotAttenuation; + if (attenuation > 0.0) + { + float shadowAttenuation = 0.0; + + if (PassType == 0 && surfaceIndex >= 0) { - vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance; - vec3 origin2 = origin + offset.x * e0 + offset.y * e1; + vec3 e0 = normalize(cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0))); + vec3 e1 = cross(normal, e0); + e0 = cross(normal, e1); + for (uint i = 0; i < SampleCount; i++) + { + vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance; + vec3 origin2 = origin + offset.x * e0 + offset.y * e1; - float dist2 = distance(light.Origin, origin2); - vec3 dir2 = normalize(light.Origin - origin2); + float dist2 = distance(light.Origin, origin2); + vec3 dir2 = normalize(light.Origin - origin2); - traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 1, 0, 1, origin2, minDistance, dir2, dist2, 0); - shadowAttenuation += payload.hitAttenuation; + traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 1, 0, 1, origin2, minDistance, dir2, dist2, 0); + shadowAttenuation += payload.hitAttenuation; + } + shadowAttenuation *= 1.0 / float(SampleCount); + } + else + { + traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 1, 0, 1, origin, minDistance, dir, dist, 0); + shadowAttenuation = payload.hitAttenuation; } - shadowAttenuation *= 1.0 / float(SampleCount); - } - else - { - traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 1, 0, 1, origin, minDistance, dir, dist, 0); - shadowAttenuation = payload.hitAttenuation; - } - attenuation *= shadowAttenuation; + attenuation *= shadowAttenuation; - incoming.rgb += light.Color * (attenuation * light.Intensity) * incoming.w; + incoming.rgb += light.Color * (attenuation * light.Intensity) * incoming.w; + } } } }