mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-01-24 16:51:08 +00:00
Improve direct light sampling quality
Fix command line argument bug
This commit is contained in:
parent
2efd031fa2
commit
973a5b28b7
4 changed files with 58 additions and 6 deletions
|
@ -309,6 +309,24 @@ struct ThingLight
|
||||||
return spotAttenuation;
|
return spotAttenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3 SpotDir() const
|
||||||
|
{
|
||||||
|
if (outerAngleCos > -1.0f)
|
||||||
|
{
|
||||||
|
float negPitch = -radians(mapThing->pitch);
|
||||||
|
float xyLen = std::cos(negPitch);
|
||||||
|
Vec3 spotDir;
|
||||||
|
spotDir.x = -std::cos(radians(mapThing->angle)) * xyLen;
|
||||||
|
spotDir.y = -std::sin(radians(mapThing->angle)) * xyLen;
|
||||||
|
spotDir.z = -std::sin(negPitch);
|
||||||
|
return spotDir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Vec3(0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float DistAttenuation(float distance) const
|
float DistAttenuation(float distance) const
|
||||||
{
|
{
|
||||||
return std::max(1.0f - (distance / LightRadius()), 0.0f);
|
return std::max(1.0f - (distance / LightRadius()), 0.0f);
|
||||||
|
|
|
@ -198,6 +198,7 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
||||||
uniforms.LightSpotDir = light.SpotDir();
|
uniforms.LightSpotDir = light.SpotDir();
|
||||||
uniforms.LightColor = light.rgb;
|
uniforms.LightColor = light.rgb;
|
||||||
uniforms.PassType = firstPass ? 0.0f : 1.0f;
|
uniforms.PassType = firstPass ? 0.0f : 1.0f;
|
||||||
|
uniforms.SampleDistance = mesh->samples;
|
||||||
firstPass = false;
|
firstPass = false;
|
||||||
|
|
||||||
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
||||||
|
@ -705,11 +706,26 @@ void GPURaytracer::CreateShaders()
|
||||||
float LightInnerAngleCos;
|
float LightInnerAngleCos;
|
||||||
float LightOuterAngleCos;
|
float LightOuterAngleCos;
|
||||||
vec3 LightSpotDir;
|
vec3 LightSpotDir;
|
||||||
float Padding1;
|
float SampleDistance;
|
||||||
vec3 LightColor;
|
vec3 LightColor;
|
||||||
float Padding2;
|
float Padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
float RadicalInverse_VdC(uint bits)
|
||||||
|
{
|
||||||
|
bits = (bits << 16u) | (bits >> 16u);
|
||||||
|
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||||
|
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||||
|
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||||
|
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||||
|
return float(bits) * 2.3283064365386963e-10f; // / 0x100000000
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 Hammersley(uint i, uint N)
|
||||||
|
{
|
||||||
|
return vec2(float(i) / float(N), RadicalInverse_VdC(i));
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
||||||
|
@ -744,8 +760,25 @@ void GPURaytracer::CreateShaders()
|
||||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||||
if (attenuation > 0.0)
|
if (attenuation > 0.0)
|
||||||
{
|
{
|
||||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin, minDistance, dir, dist, 0);
|
const uint sample_count = 1024;
|
||||||
attenuation *= payload.hitAttenuation;
|
float shadowAttenuation = 0.0;
|
||||||
|
vec3 e0 = 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 < sample_count; i++)
|
||||||
|
{
|
||||||
|
vec2 offset = (Hammersley(i, sample_count) - 0.5) * SampleDistance;
|
||||||
|
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
|
||||||
|
|
||||||
|
float dist2 = distance(LightOrigin, origin2);
|
||||||
|
vec3 dir2 = normalize(LightOrigin - origin2);
|
||||||
|
|
||||||
|
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin2, minDistance, dir2, dist2, 0);
|
||||||
|
shadowAttenuation += payload.hitAttenuation;
|
||||||
|
}
|
||||||
|
shadowAttenuation *= 1.0 / float(sample_count);
|
||||||
|
|
||||||
|
attenuation *= shadowAttenuation;
|
||||||
|
|
||||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,9 @@ struct Uniforms
|
||||||
float LightInnerAngleCos;
|
float LightInnerAngleCos;
|
||||||
float LightOuterAngleCos;
|
float LightOuterAngleCos;
|
||||||
Vec3 LightSpotDir;
|
Vec3 LightSpotDir;
|
||||||
float Padding1;
|
float SampleDistance;
|
||||||
Vec3 LightColor;
|
Vec3 LightColor;
|
||||||
float Padding2;
|
float Padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GPURaytracer
|
class GPURaytracer
|
||||||
|
|
|
@ -527,6 +527,7 @@ static void ShowUsage()
|
||||||
, SplitCost
|
, SplitCost
|
||||||
, AAPreference
|
, AAPreference
|
||||||
, (int)std::thread::hardware_concurrency()
|
, (int)std::thread::hardware_concurrency()
|
||||||
|
, Samples
|
||||||
, Multisample
|
, Multisample
|
||||||
, LightBounce
|
, LightBounce
|
||||||
, GridSize
|
, GridSize
|
||||||
|
|
Loading…
Reference in a new issue