mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-28 14:41:57 +00:00
Make the fragment shader a little more readable
This commit is contained in:
parent
0ca74c2e42
commit
f6f11af04a
1 changed files with 108 additions and 96 deletions
|
@ -61,13 +61,14 @@ layout(push_constant) uniform PushConstants
|
||||||
layout(location = 0) in vec3 worldpos;
|
layout(location = 0) in vec3 worldpos;
|
||||||
layout(location = 0) out vec4 fragcolor;
|
layout(location = 0) out vec4 fragcolor;
|
||||||
|
|
||||||
|
vec3 TraceSunLight(vec3 origin);
|
||||||
|
vec3 TraceLight(vec3 origin, vec3 normal, LightInfo light);
|
||||||
|
float TraceAmbientOcclusion(vec3 origin, vec3 normal);
|
||||||
vec2 Hammersley(uint i, uint N);
|
vec2 Hammersley(uint i, uint N);
|
||||||
float RadicalInverse_VdC(uint bits);
|
float RadicalInverse_VdC(uint bits);
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
const float minDistance = 0.01;
|
|
||||||
|
|
||||||
vec3 origin = worldpos;
|
vec3 origin = worldpos;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
if (SurfaceIndex >= 0)
|
if (SurfaceIndex >= 0)
|
||||||
|
@ -76,14 +77,107 @@ void main()
|
||||||
origin += normal * 0.1;
|
origin += normal * 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 incoming = vec3(0.0);
|
vec3 incoming = TraceSunLight(origin);
|
||||||
|
|
||||||
// Sun light
|
for (uint j = LightStart; j < LightEnd; j++)
|
||||||
{
|
{
|
||||||
const float dist = 32768.0;
|
incoming += TraceLight(origin, normal, lights[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SurfaceIndex >= 0)
|
||||||
|
{
|
||||||
|
incoming.rgb *= TraceAmbientOcclusion(origin, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
fragcolor = vec4(incoming, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 TraceLight(vec3 origin, vec3 normal, LightInfo light)
|
||||||
|
{
|
||||||
|
const float minDistance = 0.01;
|
||||||
|
vec3 incoming = vec3(0.0);
|
||||||
|
float dist = distance(light.Origin, origin);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
rayQueryEXT rayQuery;
|
||||||
|
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, dir, dist);
|
||||||
|
|
||||||
|
while(rayQueryProceedEXT(rayQuery)) { }
|
||||||
|
|
||||||
|
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT)
|
||||||
|
{
|
||||||
|
incoming.rgb += light.Color * (attenuation * light.Intensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return incoming;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 TraceSunLight(vec3 origin)
|
||||||
|
{
|
||||||
|
const float minDistance = 0.01;
|
||||||
|
vec3 incoming = vec3(0.0);
|
||||||
|
const float dist = 32768.0;
|
||||||
|
|
||||||
|
rayQueryEXT rayQuery;
|
||||||
|
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, SunDir, dist);
|
||||||
|
|
||||||
|
while(rayQueryProceedEXT(rayQuery))
|
||||||
|
{
|
||||||
|
if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCommittedIntersectionTriangleEXT)
|
||||||
|
{
|
||||||
|
rayQueryConfirmIntersectionEXT(rayQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)
|
||||||
|
{
|
||||||
|
int primitiveID = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);
|
||||||
|
SurfaceInfo surface = surfaces[surfaceIndices[primitiveID]];
|
||||||
|
incoming.rgb += SunColor * SunIntensity * surface.Sky;
|
||||||
|
}
|
||||||
|
return incoming;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TraceAmbientOcclusion(vec3 origin, vec3 normal)
|
||||||
|
{
|
||||||
|
const float minDistance = 0.05;
|
||||||
|
const float aoDistance = 100;
|
||||||
|
const int SampleCount = 2048;
|
||||||
|
|
||||||
|
vec3 N = normal;
|
||||||
|
vec3 up = abs(N.x) < abs(N.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);
|
||||||
|
vec3 tangent = normalize(cross(up, N));
|
||||||
|
vec3 bitangent = cross(N, tangent);
|
||||||
|
|
||||||
|
float ambience = 0.0f;
|
||||||
|
for (uint i = 0; i < SampleCount; i++)
|
||||||
|
{
|
||||||
|
vec2 Xi = Hammersley(i, SampleCount);
|
||||||
|
vec3 H = normalize(vec3(Xi.x * 2.0f - 1.0f, Xi.y * 2.0f - 1.0f, 1.5 - length(Xi)));
|
||||||
|
vec3 L = H.x * tangent + H.y * bitangent + H.z * N;
|
||||||
|
|
||||||
rayQueryEXT rayQuery;
|
rayQueryEXT rayQuery;
|
||||||
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, SunDir, dist);
|
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, L, aoDistance);
|
||||||
|
|
||||||
while(rayQueryProceedEXT(rayQuery))
|
while(rayQueryProceedEXT(rayQuery))
|
||||||
{
|
{
|
||||||
|
@ -97,100 +191,18 @@ void main()
|
||||||
{
|
{
|
||||||
int primitiveID = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);
|
int primitiveID = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);
|
||||||
SurfaceInfo surface = surfaces[surfaceIndices[primitiveID]];
|
SurfaceInfo surface = surfaces[surfaceIndices[primitiveID]];
|
||||||
incoming.rgb += SunColor * SunIntensity * surface.Sky;
|
if (surface.Sky == 0.0)
|
||||||
|
{
|
||||||
|
float hitDistance = rayQueryGetIntersectionTEXT(rayQuery, true);
|
||||||
|
ambience += clamp(hitDistance / aoDistance, 0.0, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
for (uint j = LightStart; j < LightEnd; j++)
|
|
||||||
{
|
|
||||||
LightInfo light = lights[j];
|
|
||||||
|
|
||||||
float dist = distance(light.Origin, origin);
|
|
||||||
if (dist > minDistance && dist < light.Radius)
|
|
||||||
{
|
{
|
||||||
vec3 dir = normalize(light.Origin - origin);
|
ambience += 1.0;
|
||||||
|
|
||||||
float distAttenuation = max(1.0 - (dist / light.Radius), 0.0);
|
|
||||||
float angleAttenuation = 1.0f;
|
|
||||||
if (SurfaceIndex >= 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)
|
|
||||||
{
|
|
||||||
rayQueryEXT rayQuery;
|
|
||||||
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, dir, dist);
|
|
||||||
|
|
||||||
while(rayQueryProceedEXT(rayQuery)) { }
|
|
||||||
|
|
||||||
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT)
|
|
||||||
{
|
|
||||||
incoming.rgb += light.Color * (attenuation * light.Intensity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ambience / float(SampleCount);
|
||||||
// Ambient occlusion
|
|
||||||
if (SurfaceIndex >= 0)
|
|
||||||
{
|
|
||||||
const float minDistance = 0.05;
|
|
||||||
const float aoDistance = 100;
|
|
||||||
const int SampleCount = 2048;
|
|
||||||
|
|
||||||
vec3 N = normal;
|
|
||||||
vec3 up = abs(N.x) < abs(N.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);
|
|
||||||
vec3 tangent = normalize(cross(up, N));
|
|
||||||
vec3 bitangent = cross(N, tangent);
|
|
||||||
|
|
||||||
float ambience = 0.0f;
|
|
||||||
for (uint i = 0; i < SampleCount; i++)
|
|
||||||
{
|
|
||||||
vec2 Xi = Hammersley(i, SampleCount);
|
|
||||||
vec3 H = normalize(vec3(Xi.x * 2.0f - 1.0f, Xi.y * 2.0f - 1.0f, 1.5 - length(Xi)));
|
|
||||||
vec3 L = H.x * tangent + H.y * bitangent + H.z * N;
|
|
||||||
|
|
||||||
rayQueryEXT rayQuery;
|
|
||||||
rayQueryInitializeEXT(rayQuery, acc, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, minDistance, L, aoDistance);
|
|
||||||
|
|
||||||
while(rayQueryProceedEXT(rayQuery))
|
|
||||||
{
|
|
||||||
if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCommittedIntersectionTriangleEXT)
|
|
||||||
{
|
|
||||||
rayQueryConfirmIntersectionEXT(rayQuery);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)
|
|
||||||
{
|
|
||||||
int primitiveID = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);
|
|
||||||
SurfaceInfo surface = surfaces[surfaceIndices[primitiveID]];
|
|
||||||
if (surface.Sky == 0.0)
|
|
||||||
{
|
|
||||||
float hitDistance = rayQueryGetIntersectionTEXT(rayQuery, true);
|
|
||||||
ambience += clamp(hitDistance / aoDistance, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ambience += 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ambience /= float(SampleCount);
|
|
||||||
|
|
||||||
incoming.rgb = incoming.rgb * ambience;
|
|
||||||
}
|
|
||||||
|
|
||||||
fragcolor = vec4(incoming, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 Hammersley(uint i, uint N)
|
vec2 Hammersley(uint i, uint N)
|
||||||
|
|
Loading…
Reference in a new issue