mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-21 19:50:54 +00:00
Discard traces via dot product for every light in GPU/CPU
This commit is contained in:
parent
42c1258fc9
commit
00ae64b79d
2 changed files with 82 additions and 77 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue