2021-11-07 03:05:19 +00:00
|
|
|
static const char* glsl_rgen_bounce = R"glsl(
|
|
|
|
|
|
|
|
#version 460
|
|
|
|
#extension GL_EXT_ray_tracing : require
|
|
|
|
|
|
|
|
struct hitPayload
|
|
|
|
{
|
2021-11-07 22:52:44 +00:00
|
|
|
vec3 hitPosition;
|
2021-11-07 03:05:19 +00:00
|
|
|
float hitAttenuation;
|
2021-11-07 22:52:44 +00:00
|
|
|
int hitSurfaceIndex;
|
2021-11-07 03:05:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
layout(location = 0) rayPayloadEXT hitPayload payload;
|
|
|
|
|
|
|
|
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
|
2021-11-07 22:52:44 +00:00
|
|
|
layout(set = 0, binding = 1, rgba32f) uniform image2D startpositions;
|
|
|
|
layout(set = 0, binding = 2, rgba32f) uniform image2D positions;
|
2021-11-07 03:05:19 +00:00
|
|
|
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
|
|
|
|
|
|
|
|
layout(set = 0, binding = 4) uniform Uniforms
|
|
|
|
{
|
2021-11-07 22:52:44 +00:00
|
|
|
uint SampleIndex;
|
|
|
|
uint SampleCount;
|
|
|
|
uint PassType;
|
2021-11-16 01:15:14 +00:00
|
|
|
uint Padding0;
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 SunDir;
|
2021-11-07 03:05:19 +00:00
|
|
|
float SampleDistance;
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 SunColor;
|
|
|
|
float SunIntensity;
|
|
|
|
vec3 HemisphereVec;
|
2021-11-07 22:52:44 +00:00
|
|
|
float Padding1;
|
2021-11-07 03:05:19 +00:00
|
|
|
};
|
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
struct SurfaceInfo
|
2021-11-07 03:05:19 +00:00
|
|
|
{
|
2021-11-07 22:52:44 +00:00
|
|
|
vec3 Normal;
|
|
|
|
float EmissiveDistance;
|
|
|
|
vec3 EmissiveColor;
|
|
|
|
float EmissiveIntensity;
|
|
|
|
float Sky;
|
|
|
|
float Padding0, Padding1, Padding2;
|
|
|
|
};
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
|
|
|
|
2021-11-16 01:15:14 +00:00
|
|
|
layout(push_constant) uniform PushConstants
|
|
|
|
{
|
|
|
|
uint LightStart;
|
|
|
|
uint LightEnd;
|
|
|
|
ivec2 pushPadding;
|
|
|
|
};
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 ImportanceSample(vec3 N);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
vec4 data0;
|
|
|
|
if (PassType == 2)
|
|
|
|
data0 = imageLoad(positions, texelPos);
|
|
|
|
else
|
|
|
|
data0 = imageLoad(startpositions, texelPos);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
vec4 incoming = vec4(0.0, 0.0, 0.0, 1.0);
|
2021-11-09 23:37:56 +00:00
|
|
|
if (PassType != 0)
|
|
|
|
incoming = imageLoad(outputs, texelPos);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-10 01:25:03 +00:00
|
|
|
vec3 origin = data0.xyz;
|
2021-11-07 22:52:44 +00:00
|
|
|
int surfaceIndex = int(data0.w);
|
2021-11-10 01:25:03 +00:00
|
|
|
if (surfaceIndex != -1)
|
2021-11-07 03:05:19 +00:00
|
|
|
{
|
2021-11-07 22:52:44 +00:00
|
|
|
if (PassType == 0)
|
2021-11-07 03:05:19 +00:00
|
|
|
{
|
2021-11-10 01:25:03 +00:00
|
|
|
if (surfaceIndex >= 0)
|
|
|
|
{
|
|
|
|
SurfaceInfo surface = surfaces[surfaceIndex];
|
|
|
|
incoming.rgb = surface.EmissiveColor * surface.EmissiveIntensity;
|
|
|
|
}
|
2021-11-07 03:05:19 +00:00
|
|
|
}
|
2021-11-07 22:52:44 +00:00
|
|
|
else
|
2021-11-07 03:05:19 +00:00
|
|
|
{
|
2021-11-07 22:52:44 +00:00
|
|
|
if (PassType == 1)
|
|
|
|
incoming.w = 1.0f / float(SampleCount);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-10 01:25:03 +00:00
|
|
|
vec3 normal;
|
|
|
|
if (surfaceIndex >= 0)
|
|
|
|
{
|
|
|
|
normal = surfaces[surfaceIndex].Normal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (SampleIndex % 6)
|
|
|
|
{
|
|
|
|
case 0: normal = vec3( 1.0f, 0.0f, 0.0f); break;
|
|
|
|
case 1: normal = vec3(-1.0f, 0.0f, 0.0f); break;
|
|
|
|
case 2: normal = vec3( 0.0f, 1.0f, 0.0f); break;
|
|
|
|
case 3: normal = vec3( 0.0f, -1.0f, 0.0f); break;
|
|
|
|
case 4: normal = vec3( 0.0f, 0.0f, 1.0f); break;
|
|
|
|
case 5: normal = vec3( 0.0f, 0.0f, -1.0f); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 H = ImportanceSample(normal);
|
2021-11-07 22:52:44 +00:00
|
|
|
vec3 L = normalize(H * (2.0f * dot(normal, H)) - normal);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
float NdotL = max(dot(normal, L), 0.0);
|
2021-11-07 03:05:19 +00:00
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
const float p = 1 / (2 * 3.14159265359);
|
|
|
|
incoming.w *= NdotL / p;
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
surfaceIndex = -1;
|
2021-11-07 22:52:44 +00:00
|
|
|
if (NdotL > 0.0f)
|
|
|
|
{
|
|
|
|
const float minDistance = 0.1;
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin + normal * 0.1, minDistance, L, 32768, 0);
|
2021-11-07 22:52:44 +00:00
|
|
|
if (payload.hitAttenuation == 1.0)
|
|
|
|
{
|
|
|
|
surfaceIndex = payload.hitSurfaceIndex;
|
2021-11-10 01:25:03 +00:00
|
|
|
SurfaceInfo surface = surfaces[surfaceIndex];
|
2021-11-07 22:52:44 +00:00
|
|
|
if (surface.EmissiveDistance > 0.0)
|
|
|
|
{
|
2021-11-11 04:04:33 +00:00
|
|
|
float hitDistance = distance(origin, payload.hitPosition);
|
2021-11-07 22:52:44 +00:00
|
|
|
float attenuation = max(1.0 - (hitDistance / surface.EmissiveDistance), 0.0f);
|
|
|
|
incoming.rgb += surface.EmissiveColor * (surface.EmissiveIntensity * attenuation * incoming.w);
|
|
|
|
}
|
2021-11-11 04:04:33 +00:00
|
|
|
origin = payload.hitPosition;
|
2021-11-07 22:52:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
incoming.w *= 0.25; // the amount of incoming light the surfaces emit
|
2021-11-07 03:05:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-10 01:25:03 +00:00
|
|
|
data0.xyz = origin;
|
|
|
|
data0.w = float(surfaceIndex);
|
|
|
|
|
2021-11-07 22:52:44 +00:00
|
|
|
imageStore(positions, texelPos, data0);
|
|
|
|
imageStore(outputs, texelPos, incoming);
|
|
|
|
}
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 ImportanceSample(vec3 N)
|
2021-11-07 22:52:44 +00:00
|
|
|
{
|
|
|
|
// from tangent-space vector to world-space sample vector
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 up = abs(N.x) < abs(N.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);
|
2021-11-07 22:52:44 +00:00
|
|
|
vec3 tangent = normalize(cross(up, N));
|
|
|
|
vec3 bitangent = cross(N, tangent);
|
|
|
|
|
2021-11-09 23:37:56 +00:00
|
|
|
vec3 sampleVec = tangent * HemisphereVec.x + bitangent * HemisphereVec.y + N * HemisphereVec.z;
|
2021-11-07 22:52:44 +00:00
|
|
|
return normalize(sampleVec);
|
|
|
|
}
|
|
|
|
|
2021-11-07 03:05:19 +00:00
|
|
|
)glsl";
|