mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-29 07:02:18 +00:00
Move glsl shader code to files
This commit is contained in:
parent
973a5b28b7
commit
75798fae9b
6 changed files with 172 additions and 168 deletions
|
@ -172,6 +172,9 @@ set( SOURCES
|
||||||
src/lightmap/stacktrace.h
|
src/lightmap/stacktrace.h
|
||||||
src/lightmap/gpuraytracer.cpp
|
src/lightmap/gpuraytracer.cpp
|
||||||
src/lightmap/gpuraytracer.h
|
src/lightmap/gpuraytracer.h
|
||||||
|
src/lightmap/glsl_closesthit.h
|
||||||
|
src/lightmap/glsl_miss.h
|
||||||
|
src/lightmap/glsl_raygen.h
|
||||||
src/math/angle.cpp
|
src/math/angle.cpp
|
||||||
src/math/bounds.cpp
|
src/math/bounds.cpp
|
||||||
src/math/mathlib.cpp
|
src/math/mathlib.cpp
|
||||||
|
|
18
src/lightmap/glsl_closesthit.h
Normal file
18
src/lightmap/glsl_closesthit.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
static const char* glsl_closesthit = 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";
|
18
src/lightmap/glsl_miss.h
Normal file
18
src/lightmap/glsl_miss.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
static const char* glsl_miss = 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";
|
109
src/lightmap/glsl_raygen.h
Normal file
109
src/lightmap/glsl_raygen.h
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
static const char* glsl_raygen = 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;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
const uint sample_count = 1024;
|
||||||
|
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";
|
|
@ -15,6 +15,9 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "renderdoc_app.h"
|
#include "renderdoc_app.h"
|
||||||
|
#include "glsl_raygen.h"
|
||||||
|
#include "glsl_miss.h"
|
||||||
|
#include "glsl_closesthit.h"
|
||||||
|
|
||||||
extern int Multisample;
|
extern int Multisample;
|
||||||
extern int LightBounce;
|
extern int LightBounce;
|
||||||
|
@ -198,7 +201,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;
|
uniforms.SampleDistance = (float)mesh->samples;
|
||||||
firstPass = false;
|
firstPass = false;
|
||||||
|
|
||||||
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
||||||
|
@ -673,175 +676,20 @@ void GPURaytracer::CreateTopLevelAccelerationStructure()
|
||||||
|
|
||||||
void GPURaytracer::CreateShaders()
|
void GPURaytracer::CreateShaders()
|
||||||
{
|
{
|
||||||
static bool firstCall = true;
|
ShaderBuilder builder1;
|
||||||
if (firstCall)
|
builder1.setRayGenShader(glsl_raygen);
|
||||||
{
|
shaderRayGen = builder1.create(device.get());
|
||||||
ShaderBuilder::init();
|
|
||||||
firstCall = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string code = R"(
|
|
||||||
#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;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
const uint sample_count = 1024;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
ShaderBuilder builder;
|
|
||||||
builder.setRayGenShader(code);
|
|
||||||
shaderRayGen = builder.create(device.get());
|
|
||||||
shaderRayGen->SetDebugName("shaderRayGen");
|
shaderRayGen->SetDebugName("shaderRayGen");
|
||||||
}
|
|
||||||
|
|
||||||
{
|
ShaderBuilder builder2;
|
||||||
std::string code = R"(
|
builder2.setMissShader(glsl_miss);
|
||||||
#version 460
|
shaderMiss = builder2.create(device.get());
|
||||||
#extension GL_EXT_ray_tracing : require
|
|
||||||
|
|
||||||
struct hitPayload
|
|
||||||
{
|
|
||||||
float hitAttenuation;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
payload.hitAttenuation = 1.0;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
ShaderBuilder builder;
|
|
||||||
builder.setMissShader(code);
|
|
||||||
shaderMiss = builder.create(device.get());
|
|
||||||
shaderMiss->SetDebugName("shaderMiss");
|
shaderMiss->SetDebugName("shaderMiss");
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string code = R"(
|
|
||||||
#version 460
|
|
||||||
#extension GL_EXT_ray_tracing : require
|
|
||||||
|
|
||||||
struct hitPayload
|
|
||||||
{
|
|
||||||
float hitAttenuation;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
payload.hitAttenuation = 0.0;
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
ShaderBuilder builder;
|
ShaderBuilder builder;
|
||||||
builder.setClosestHitShader(code);
|
builder.setClosestHitShader(glsl_closesthit);
|
||||||
shaderClosestHit = builder.create(device.get());
|
shaderClosestHit = builder.create(device.get());
|
||||||
shaderClosestHit->SetDebugName("shaderClosestHit");
|
shaderClosestHit->SetDebugName("shaderClosestHit");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPURaytracer::CreatePipeline()
|
void GPURaytracer::CreatePipeline()
|
||||||
|
|
|
@ -121,6 +121,14 @@ void ShaderBuilder::deinit()
|
||||||
|
|
||||||
ShaderBuilder::ShaderBuilder()
|
ShaderBuilder::ShaderBuilder()
|
||||||
{
|
{
|
||||||
|
class InitShaderLib
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InitShaderLib() { ShaderBuilder::init(); }
|
||||||
|
~InitShaderLib() { ShaderBuilder::deinit(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static InitShaderLib init;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBuilder::setVertexShader(const std::string &c) { code = c; stage = EShLanguage::EShLangVertex; }
|
void ShaderBuilder::setVertexShader(const std::string &c) { code = c; stage = EShLanguage::EShLangVertex; }
|
||||||
|
|
Loading…
Reference in a new issue