Discard traces via dot product for every light in GPU/CPU

This commit is contained in:
RaveYard 2022-07-05 09:19:52 +02:00
parent 42c1258fc9
commit 00ae64b79d
2 changed files with 82 additions and 77 deletions

View file

@ -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);
}
}
}
}

View file

@ -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;
}
}
}
}