mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-10 06:41:37 +00:00
Split shaders into three types (light, sun, bounce)
This commit is contained in:
parent
9ce4c027bd
commit
8df36944eb
16 changed files with 915 additions and 595 deletions
|
@ -170,9 +170,15 @@ set( SOURCES
|
|||
src/lightmap/stacktrace.h
|
||||
src/lightmap/gpuraytracer.cpp
|
||||
src/lightmap/gpuraytracer.h
|
||||
src/lightmap/glsl_closesthit.h
|
||||
src/lightmap/glsl_miss.h
|
||||
src/lightmap/glsl_raygen.h
|
||||
src/lightmap/glsl_rchit_bounce.h
|
||||
src/lightmap/glsl_rchit_light.h
|
||||
src/lightmap/glsl_rchit_sun.h
|
||||
src/lightmap/glsl_rgen_bounce.h
|
||||
src/lightmap/glsl_rgen_light.h
|
||||
src/lightmap/glsl_rgen_sun.h
|
||||
src/lightmap/glsl_rmiss_bounce.h
|
||||
src/lightmap/glsl_rmiss_light.h
|
||||
src/lightmap/glsl_rmiss_sun.h
|
||||
src/math/angle.cpp
|
||||
src/math/bounds.cpp
|
||||
src/math/mathlib.cpp
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
static const char* glsl_raygen = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D positions;
|
||||
layout(set = 0, binding = 2, rgba32f) uniform image2D normals;
|
||||
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
|
||||
|
||||
layout(set = 0, binding = 4) uniform Uniforms
|
||||
{
|
||||
vec3 LightOrigin;
|
||||
float PassType;
|
||||
float LightRadius;
|
||||
float LightIntensity;
|
||||
float LightInnerAngleCos;
|
||||
float LightOuterAngleCos;
|
||||
vec3 LightSpotDir;
|
||||
float SampleDistance;
|
||||
vec3 LightColor;
|
||||
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()
|
||||
{
|
||||
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
||||
vec4 data0 = imageLoad(positions, texelPos);
|
||||
vec4 data1 = imageLoad(normals, texelPos);
|
||||
if (data1 == vec4(0))
|
||||
return;
|
||||
|
||||
vec3 origin = data0.xyz;
|
||||
vec3 normal = data1.xyz;
|
||||
|
||||
vec4 emittance = vec4(0.0);
|
||||
if (PassType == 1.0)
|
||||
emittance = imageLoad(outputs, texelPos);
|
||||
|
||||
const float minDistance = 0.01;
|
||||
const uint sample_count = 1024;
|
||||
|
||||
payload.isSkyRay = (PassType == 0.0);
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
float dist = distance(LightOrigin, origin);
|
||||
if (dist > minDistance && dist < LightRadius)
|
||||
{
|
||||
vec3 dir = normalize(LightOrigin - origin);
|
||||
|
||||
float distAttenuation = max(1.0 - (dist / LightRadius), 0.0);
|
||||
float angleAttenuation = max(dot(normal, dir), 0.0);
|
||||
float spotAttenuation = 1.0;
|
||||
if (LightOuterAngleCos > -1.0)
|
||||
{
|
||||
float cosDir = dot(dir, LightSpotDir);
|
||||
spotAttenuation = smoothstep(LightOuterAngleCos, LightInnerAngleCos, cosDir);
|
||||
spotAttenuation = max(spotAttenuation, 0.0);
|
||||
}
|
||||
|
||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
origin += normal * 0.1;
|
||||
|
||||
float attenuation = 0.0;
|
||||
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 = 32768.0;
|
||||
vec3 dir2 = LightSpotDir;
|
||||
|
||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin2, minDistance, dir2, dist2, 0);
|
||||
attenuation += payload.hitAttenuation;
|
||||
}
|
||||
attenuation *= 1.0 / float(sample_count);
|
||||
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
}
|
||||
|
||||
emittance.w += 1.0;
|
||||
imageStore(outputs, texelPos, emittance);
|
||||
}
|
||||
|
||||
)glsl";
|
33
src/lightmap/glsl_rchit_bounce.h
Normal file
33
src/lightmap/glsl_rchit_bounce.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
static const char* glsl_rchit_bounce = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
{
|
||||
vec3 Normal;
|
||||
float EmissiveDistance;
|
||||
vec3 EmissiveColor;
|
||||
float EmissiveIntensity;
|
||||
float Sky;
|
||||
float Padding0, Padding1, Padding2;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 5) buffer SurfaceIndexBuffer { int surfaceIndices[]; };
|
||||
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||
|
||||
void main()
|
||||
{
|
||||
// SurfaceInfo surface = surfaces[surfaceIndices[gl_PrimitiveID]];
|
||||
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
|
||||
)glsl";
|
33
src/lightmap/glsl_rchit_light.h
Normal file
33
src/lightmap/glsl_rchit_light.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
static const char* glsl_rchit_light = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
{
|
||||
vec3 Normal;
|
||||
float EmissiveDistance;
|
||||
vec3 EmissiveColor;
|
||||
float EmissiveIntensity;
|
||||
float Sky;
|
||||
float Padding0, Padding1, Padding2;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 5) buffer SurfaceIndexBuffer { int surfaceIndices[]; };
|
||||
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||
|
||||
void main()
|
||||
{
|
||||
//SurfaceInfo surface = surfaces[surfaceIndices[gl_PrimitiveID]];
|
||||
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
|
||||
)glsl";
|
|
@ -1,4 +1,4 @@
|
|||
static const char* glsl_closesthit = R"glsl(
|
||||
static const char* glsl_rchit_sun = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
@ -6,7 +6,6 @@ static const char* glsl_closesthit = R"glsl(
|
|||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
|
@ -27,15 +26,7 @@ layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
|||
void main()
|
||||
{
|
||||
SurfaceInfo surface = surfaces[surfaceIndices[gl_PrimitiveID]];
|
||||
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.hitAttenuation = surface.Sky;
|
||||
}
|
||||
payload.hitAttenuation = surface.Sky;
|
||||
}
|
||||
|
||||
)glsl";
|
110
src/lightmap/glsl_rgen_bounce.h
Normal file
110
src/lightmap/glsl_rgen_bounce.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
static const char* glsl_rgen_bounce = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D positions;
|
||||
layout(set = 0, binding = 2, rgba32f) uniform image2D normals;
|
||||
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
|
||||
|
||||
layout(set = 0, binding = 4) uniform Uniforms
|
||||
{
|
||||
vec3 LightOrigin;
|
||||
float PassType;
|
||||
float LightRadius;
|
||||
float LightIntensity;
|
||||
float LightInnerAngleCos;
|
||||
float LightOuterAngleCos;
|
||||
vec3 LightSpotDir;
|
||||
float SampleDistance;
|
||||
vec3 LightColor;
|
||||
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()
|
||||
{
|
||||
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
||||
vec4 data0 = imageLoad(positions, texelPos);
|
||||
vec4 data1 = imageLoad(normals, texelPos);
|
||||
if (data1 == vec4(0))
|
||||
return;
|
||||
|
||||
vec3 origin = data0.xyz;
|
||||
vec3 normal = data1.xyz;
|
||||
|
||||
vec4 emittance = vec4(0.0);
|
||||
if (PassType == 1.0)
|
||||
emittance = imageLoad(outputs, texelPos);
|
||||
|
||||
const float minDistance = 0.01;
|
||||
const uint sample_count = 1024;
|
||||
|
||||
float dist = distance(LightOrigin, origin);
|
||||
if (dist > minDistance && dist < LightRadius)
|
||||
{
|
||||
vec3 dir = normalize(LightOrigin - origin);
|
||||
|
||||
float distAttenuation = max(1.0 - (dist / LightRadius), 0.0);
|
||||
float angleAttenuation = max(dot(normal, dir), 0.0);
|
||||
float spotAttenuation = 1.0;
|
||||
if (LightOuterAngleCos > -1.0)
|
||||
{
|
||||
float cosDir = dot(dir, LightSpotDir);
|
||||
spotAttenuation = smoothstep(LightOuterAngleCos, LightInnerAngleCos, cosDir);
|
||||
spotAttenuation = max(spotAttenuation, 0.0);
|
||||
}
|
||||
|
||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
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.w += 1.0;
|
||||
imageStore(outputs, texelPos, emittance);
|
||||
}
|
||||
|
||||
)glsl";
|
110
src/lightmap/glsl_rgen_light.h
Normal file
110
src/lightmap/glsl_rgen_light.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
static const char* glsl_rgen_light = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D positions;
|
||||
layout(set = 0, binding = 2, rgba32f) uniform image2D normals;
|
||||
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
|
||||
|
||||
layout(set = 0, binding = 4) uniform Uniforms
|
||||
{
|
||||
vec3 LightOrigin;
|
||||
float PassType;
|
||||
float LightRadius;
|
||||
float LightIntensity;
|
||||
float LightInnerAngleCos;
|
||||
float LightOuterAngleCos;
|
||||
vec3 LightSpotDir;
|
||||
float SampleDistance;
|
||||
vec3 LightColor;
|
||||
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()
|
||||
{
|
||||
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
||||
vec4 data0 = imageLoad(positions, texelPos);
|
||||
vec4 data1 = imageLoad(normals, texelPos);
|
||||
if (data1 == vec4(0))
|
||||
return;
|
||||
|
||||
vec3 origin = data0.xyz;
|
||||
vec3 normal = data1.xyz;
|
||||
|
||||
vec4 emittance = vec4(0.0);
|
||||
if (PassType == 1.0)
|
||||
emittance = imageLoad(outputs, texelPos);
|
||||
|
||||
const float minDistance = 0.01;
|
||||
const uint sample_count = 1024;
|
||||
|
||||
float dist = distance(LightOrigin, origin);
|
||||
if (dist > minDistance && dist < LightRadius)
|
||||
{
|
||||
vec3 dir = normalize(LightOrigin - origin);
|
||||
|
||||
float distAttenuation = max(1.0 - (dist / LightRadius), 0.0);
|
||||
float angleAttenuation = max(dot(normal, dir), 0.0);
|
||||
float spotAttenuation = 1.0;
|
||||
if (LightOuterAngleCos > -1.0)
|
||||
{
|
||||
float cosDir = dot(dir, LightSpotDir);
|
||||
spotAttenuation = smoothstep(LightOuterAngleCos, LightInnerAngleCos, cosDir);
|
||||
spotAttenuation = max(spotAttenuation, 0.0);
|
||||
}
|
||||
|
||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
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, 1, 0, 1, origin2, minDistance, dir2, dist2, 0);
|
||||
shadowAttenuation += payload.hitAttenuation;
|
||||
}
|
||||
shadowAttenuation *= 1.0 / float(sample_count);
|
||||
|
||||
attenuation *= shadowAttenuation;
|
||||
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
emittance.w += 1.0;
|
||||
imageStore(outputs, texelPos, emittance);
|
||||
}
|
||||
|
||||
)glsl";
|
90
src/lightmap/glsl_rgen_sun.h
Normal file
90
src/lightmap/glsl_rgen_sun.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
static const char* glsl_rgen_sun = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 0) uniform accelerationStructureEXT acc;
|
||||
layout(set = 0, binding = 1, rgba32f) uniform image2D positions;
|
||||
layout(set = 0, binding = 2, rgba32f) uniform image2D normals;
|
||||
layout(set = 0, binding = 3, rgba32f) uniform image2D outputs;
|
||||
|
||||
layout(set = 0, binding = 4) uniform Uniforms
|
||||
{
|
||||
vec3 LightOrigin;
|
||||
float PassType;
|
||||
float LightRadius;
|
||||
float LightIntensity;
|
||||
float LightInnerAngleCos;
|
||||
float LightOuterAngleCos;
|
||||
vec3 LightSpotDir;
|
||||
float SampleDistance;
|
||||
vec3 LightColor;
|
||||
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()
|
||||
{
|
||||
ivec2 texelPos = ivec2(gl_LaunchIDEXT.xy);
|
||||
vec4 data0 = imageLoad(positions, texelPos);
|
||||
vec4 data1 = imageLoad(normals, texelPos);
|
||||
if (data1 == vec4(0))
|
||||
return;
|
||||
|
||||
vec3 origin = data0.xyz;
|
||||
vec3 normal = data1.xyz;
|
||||
|
||||
vec4 emittance = vec4(0.0);
|
||||
if (PassType == 1.0)
|
||||
emittance = imageLoad(outputs, texelPos);
|
||||
|
||||
const float minDistance = 0.01;
|
||||
const uint sample_count = 1024;
|
||||
|
||||
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);
|
||||
|
||||
origin += normal * 0.1;
|
||||
|
||||
float attenuation = 0.0;
|
||||
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 = 32768.0;
|
||||
vec3 dir2 = LightSpotDir;
|
||||
|
||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 2, 0, 2, origin2, minDistance, dir2, dist2, 0);
|
||||
attenuation += payload.hitAttenuation;
|
||||
}
|
||||
attenuation *= 1.0 / float(sample_count);
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
|
||||
emittance.w += 1.0;
|
||||
imageStore(outputs, texelPos, emittance);
|
||||
}
|
||||
|
||||
)glsl";
|
|
@ -1,4 +1,4 @@
|
|||
static const char* glsl_miss = R"glsl(
|
||||
static const char* glsl_rmiss_bounce = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
@ -6,21 +6,13 @@ static const char* glsl_miss = R"glsl(
|
|||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
payload.hitAttenuation = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
|
||||
)glsl";
|
18
src/lightmap/glsl_rmiss_light.h
Normal file
18
src/lightmap/glsl_rmiss_light.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
static const char* glsl_rmiss_light = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
void main()
|
||||
{
|
||||
payload.hitAttenuation = 1.0;
|
||||
}
|
||||
|
||||
)glsl";
|
18
src/lightmap/glsl_rmiss_sun.h
Normal file
18
src/lightmap/glsl_rmiss_sun.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
static const char* glsl_rmiss_sun = R"glsl(
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
void main()
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
|
||||
)glsl";
|
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,11 @@ struct SurfaceInfo
|
|||
float Padding0, Padding1, Padding2;
|
||||
};
|
||||
|
||||
struct SurfaceTask
|
||||
{
|
||||
int surf, x, y;
|
||||
};
|
||||
|
||||
class GPURaytracer
|
||||
{
|
||||
public:
|
||||
|
@ -39,13 +44,23 @@ public:
|
|||
void Raytrace(LevelMesh* level);
|
||||
|
||||
private:
|
||||
void CreateVulkanObjects();
|
||||
void CreateVertexAndIndexBuffers();
|
||||
void CreateBottomLevelAccelerationStructure();
|
||||
void CreateTopLevelAccelerationStructure();
|
||||
void CreateShaders();
|
||||
std::unique_ptr<VulkanShader> CompileRayGenShader(const char* code, const char* name);
|
||||
std::unique_ptr<VulkanShader> CompileClosestHitShader(const char* code, const char* name);
|
||||
std::unique_ptr<VulkanShader> CompileMissShader(const char* code, const char* name);
|
||||
void CreatePipeline();
|
||||
void CreateDescriptorSet();
|
||||
|
||||
void UploadTasks(const std::vector<SurfaceTask>& tasks);
|
||||
void RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddressRegionKHR& rgenShader);
|
||||
void DownloadTasks(const std::vector<SurfaceTask>& tasks);
|
||||
|
||||
void PrintVulkanInfo();
|
||||
|
||||
void RaytraceProbeSample(LightProbeSample* probe);
|
||||
void RaytraceSurfaceSample(Surface* surface, int x, int y);
|
||||
Vec3 TracePath(const Vec3& pos, const Vec3& dir, int sampleIndex, int depth = 0);
|
||||
|
@ -79,9 +94,9 @@ private:
|
|||
std::unique_ptr<VulkanBuffer> tlAccelStructBuffer;
|
||||
std::unique_ptr<VulkanAccelerationStructure> tlAccelStruct;
|
||||
|
||||
std::unique_ptr<VulkanShader> shaderRayGen;
|
||||
std::unique_ptr<VulkanShader> shaderMiss;
|
||||
std::unique_ptr<VulkanShader> shaderClosestHit;
|
||||
std::unique_ptr<VulkanShader> rgenBounce, rgenLight, rgenSun;
|
||||
std::unique_ptr<VulkanShader> rmissBounce, rmissLight, rmissSun;
|
||||
std::unique_ptr<VulkanShader> rchitBounce, rchitLight, rchitSun;
|
||||
|
||||
std::unique_ptr<VulkanDescriptorSetLayout> descriptorSetLayout;
|
||||
|
||||
|
@ -90,7 +105,7 @@ private:
|
|||
std::unique_ptr<VulkanBuffer> shaderBindingTable;
|
||||
std::unique_ptr<VulkanBuffer> sbtTransferBuffer;
|
||||
|
||||
VkStridedDeviceAddressRegionKHR rgenRegion = {};
|
||||
VkStridedDeviceAddressRegionKHR rgenBounceRegion = {}, rgenLightRegion = {}, rgenSunRegion = {};
|
||||
VkStridedDeviceAddressRegionKHR missRegion = {};
|
||||
VkStridedDeviceAddressRegionKHR hitRegion = {};
|
||||
VkStridedDeviceAddressRegionKHR callRegion = {};
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
|
||||
#include "vulkandevice.h"
|
||||
#include "vulkanobjects.h"
|
||||
#include "stacktrace.h"
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
VulkanDevice::VulkanDevice(int vk_device, bool vk_debug, std::function<void(const char* typestr, const std::string& msg)> printLogCallback) : vk_device(vk_device), vk_debug(vk_debug), printLogCallback(printLogCallback)
|
||||
VulkanDevice::VulkanDevice(int vk_device, bool vk_debug) : vk_device(vk_device), vk_debug(vk_debug)
|
||||
{
|
||||
if (HMODULE mod = GetModuleHandle(TEXT("renderdoc.dll")))
|
||||
{
|
||||
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI");
|
||||
int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_4_2, (void**)&renderdoc);
|
||||
if (ret != 1)
|
||||
renderdoc = nullptr;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
initVolk();
|
||||
|
@ -391,8 +400,11 @@ VkBool32 VulkanDevice::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT mess
|
|||
typestr = "vulkan";
|
||||
}
|
||||
|
||||
if (device->printLogCallback)
|
||||
device->printLogCallback(typestr, msg);
|
||||
printf("\n[%s] %s\n", typestr, msg.c_str());
|
||||
|
||||
std::string callstack = CaptureStackTraceText(0);
|
||||
if (!callstack.empty())
|
||||
printf("%s\n", callstack.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "volk/volk.h"
|
||||
#include "vk_mem_alloc/vk_mem_alloc.h"
|
||||
#include "renderdoc_app.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#undef min
|
||||
|
@ -45,7 +46,7 @@ public:
|
|||
class VulkanDevice
|
||||
{
|
||||
public:
|
||||
VulkanDevice(int vk_device = 0, bool vk_debug = false, std::function<void(const char* typestr, const std::string& msg)> printLogCallback = {});
|
||||
VulkanDevice(int vk_device = 0, bool vk_debug = false);
|
||||
~VulkanDevice();
|
||||
|
||||
void setDebugObjectName(const char *name, uint64_t handle, VkObjectType type)
|
||||
|
@ -102,12 +103,13 @@ public:
|
|||
std::vector<VulkanPhysicalDevice> availableDevices;
|
||||
std::vector<VulkanCompatibleDevice> supportedDevices;
|
||||
|
||||
RENDERDOC_API_1_4_2* renderdoc = nullptr;
|
||||
|
||||
static void initVolk();
|
||||
|
||||
private:
|
||||
int vk_device;
|
||||
bool vk_debug;
|
||||
std::function<void(const char* typestr, const std::string& msg)> printLogCallback;
|
||||
|
||||
void createInstance();
|
||||
//void createSurface();
|
||||
|
|
|
@ -117,6 +117,7 @@ int NumThreads = 0;
|
|||
int LMDims = 1024;
|
||||
int Samples = 8;
|
||||
bool CPURaytrace = false;
|
||||
bool VKDebug = false;
|
||||
int LightBounce = 1;
|
||||
float GridSize = 32.0f;
|
||||
|
||||
|
@ -159,10 +160,11 @@ static option long_opts[] =
|
|||
{"cpu-raytrace", no_argument, 0, 'C'},
|
||||
{"bounce", required_argument, 0, 'B'},
|
||||
{"gridsize", required_argument, 0, 'i'},
|
||||
{"vkdebug", no_argument, 0, 'D'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:Q:S:C";
|
||||
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:Q:S:CD";
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
|
@ -452,6 +454,9 @@ static void ParseArgs(int argc, char **argv)
|
|||
case 'C':
|
||||
CPURaytrace = true;
|
||||
break;
|
||||
case 'D':
|
||||
VKDebug = true;
|
||||
break;
|
||||
case 'B':
|
||||
LightBounce = atoi(optarg);
|
||||
if (LightBounce < 0) LightBounce = 0;
|
||||
|
@ -512,6 +517,7 @@ static void ShowUsage()
|
|||
" -i, --gridsize=NNN Automatic light probe grid size, floating point\n"
|
||||
" Lower values increase granularity at the expense of performance\n"
|
||||
" Recommended: 32.0, 64.0, 128.0, etc (default %.1f)\n"
|
||||
" -D, --vkdebug Print messages from the vulkan validation layer\n"
|
||||
" -w, --warn Show warning messages\n"
|
||||
#if HAVE_TIMING
|
||||
" -t, --no-timing Suppress timing information\n"
|
||||
|
|
Loading…
Reference in a new issue