From a64e85601c3d9fbd630d5d377e7c7cc168315e0e Mon Sep 17 00:00:00 2001 From: Stefan Zellmann Date: Sun, 13 Oct 2024 15:50:11 +0200 Subject: [PATCH] Use real light dist for shadow offset computation --- renderer/DirectLight_impl.cpp | 6 ++--- renderer/Raycast_impl.cpp | 4 ++-- renderer/common.h | 41 +++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/renderer/DirectLight_impl.cpp b/renderer/DirectLight_impl.cpp index 8075beaa..6db5197f 100644 --- a/renderer/DirectLight_impl.cpp +++ b/renderer/DirectLight_impl.cpp @@ -174,10 +174,10 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID, viewDir, ls.dir, ls.intensity); - shadedColor = shadedColor * safe_rcp(ls.pdf) / (ls.dist*ls.dist); + shadedColor = shadedColor * safe_rcp(ls.pdf) / ls.dist2; } else - shadedColor = hrv.albedo * ls.intensity * safe_rcp(ls.pdf) / (ls.dist*ls.dist); + shadedColor = hrv.albedo * ls.intensity * safe_rcp(ls.pdf) / ls.dist2; } else { const auto &geom = onDevice.geometries[group.geoms[hr.geom_id]]; const auto &mat = onDevice.materials[group.materials[hr.geom_id]]; @@ -190,7 +190,7 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID, viewDir, ls.dir, ls.intensity); - shadedColor = shadedColor * safe_rcp(ls.pdf) / (ls.dist*ls.dist); + shadedColor = shadedColor * safe_rcp(ls.pdf) / ls.dist2; } } else if (rendererState.renderMode == RenderMode::Ng) diff --git a/renderer/Raycast_impl.cpp b/renderer/Raycast_impl.cpp index 6a3e9002..4dbedde7 100644 --- a/renderer/Raycast_impl.cpp +++ b/renderer/Raycast_impl.cpp @@ -66,7 +66,7 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID, for (unsigned lightID=0; lightID ls = sampleLight(light, hitPos, ss.random); + LightSample ls = sampleLight(light, hitPos, ss.random); float3 brdf = evalMaterial(mat, onDevice.samplers, @@ -76,7 +76,7 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID, viewDir, ls.dir, ls.intensity); - shadedColor += brdf / ls.pdf / (ls.dist*ls.dist); + shadedColor += brdf / ls.pdf / ls.dist2; } shadedColor += diff --git a/renderer/common.h b/renderer/common.h index 11f0c7a6..ff03caa6 100644 --- a/renderer/common.h +++ b/renderer/common.h @@ -741,27 +741,46 @@ inline vec3 evalMaterial(const dco::Material &mat, return shadedColor; } -typedef light_sample LightSample; +struct LightSample : light_sample +{ + float3 intensity; + float3 dir; + float pdf; + float dist; + float dist2; +}; VSNRAY_FUNC inline LightSample sampleLight(const dco::Light &light, vec3f hitPos, Random &rnd) { LightSample result; + light_sample ls; if (light.type == dco::Light::Point) { - result = light.asPoint.sample(hitPos, rnd); - result.intensity = light.asPoint.intensity(hitPos); + ls = light.asPoint.sample(hitPos, rnd); + ls.intensity = light.asPoint.intensity(hitPos); } else if (light.type == dco::Light::Quad) { - result = light.asQuad.sample(hitPos, rnd); - result.intensity = light.asQuad.intensity(hitPos); + ls = light.asQuad.sample(hitPos, rnd); + ls.intensity = light.asQuad.intensity(hitPos); } else if (light.type == dco::Light::Directional) { - result = light.asDirectional.sample(hitPos, rnd); - result.intensity = light.asDirectional.intensity(hitPos); + ls = light.asDirectional.sample(hitPos, rnd); + ls.intensity = light.asDirectional.intensity(hitPos); } else if (light.type == dco::Light::HDRI) { - result = light.asHDRI.sample(hitPos, rnd); - result.intensity = light.asHDRI.intensity(result.dir); + ls = light.asHDRI.sample(hitPos, rnd); + ls.intensity = light.asHDRI.intensity(result.dir); } - float dist = result.dist; - result.dist = light.type == dco::Light::Directional||dco::Light::HDRI ? 1.f : dist; + + result.intensity = ls.intensity; + result.dir = ls.dir; + result.pdf = ls.pdf; + result.dist = ls.dist; + + if (light.type == dco::Light::Directional + ||light.type == dco::Light::HDRI) { + result.dist2 = 1.f; // infinite lights are not attenuated by distance! + } else { + result.dist2 = ls.dist*ls.dist; + } + return result; }