zdray/src/lightmap/glsl_rgen_ambient.h
2021-11-25 01:13:53 +01:00

111 lines
2.7 KiB
C

static const char* glsl_rgen_ambient = R"glsl(
#version 460
#extension GL_EXT_ray_tracing : require
struct hitPayload
{
vec3 hitPosition;
float hitAttenuation;
int hitSurfaceIndex;
};
layout(location = 0) rayPayloadEXT hitPayload payload;
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
layout(set = 0, binding = 1, rgba32f) uniform image2D startpositions;
layout(set = 0, binding = 2, rgba32f) uniform image2D positions;
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
layout(set = 0, binding = 4) uniform Uniforms
{
uint SampleIndex;
uint SampleCount;
uint PassType;
uint Padding0;
vec3 SunDir;
float SampleDistance;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;
float Padding1;
};
struct SurfaceInfo
{
vec3 Normal;
float EmissiveDistance;
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
};
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
layout(push_constant) uniform PushConstants
{
uint LightStart;
uint LightEnd;
ivec2 pushPadding;
};
vec2 Hammersley(uint i, uint N);
float RadicalInverse_VdC(uint bits);
void main()
{
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
vec4 data0 = imageLoad(startpositions, texelPos);
vec4 incoming = imageLoad(outputs, texelPos);
if (PassType == 1)
incoming.rgb = vec3(1.0); // For debugging
vec3 origin = data0.xyz;
int surfaceIndex = int(data0.w);
if (surfaceIndex >= 0)
{
const float minDistance = 0.05;
const float aoDistance = 100;
vec3 N = surfaces[surfaceIndex].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;
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 3, 0, 3, origin, minDistance, L, 32768, 0);
ambience += clamp(payload.hitAttenuation / aoDistance, 0.0, 1.0);
}
ambience /= float(SampleCount);
incoming.rgb = incoming.rgb * ambience;
}
imageStore(outputs, texelPos, incoming);
}
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i) / float(N), RadicalInverse_VdC(i));
}
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
}
)glsl";