diff --git a/data/shaders/deferredshadows/debug.frag b/data/shaders/deferredshadows/debug.frag new file mode 100644 index 00000000..821de26f --- /dev/null +++ b/data/shaders/deferredshadows/debug.frag @@ -0,0 +1,43 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (binding = 1) uniform sampler2D samplerPosition; +layout (binding = 2) uniform sampler2D samplerNormal; +layout (binding = 3) uniform sampler2D samplerAlbedo; +layout (binding = 5) uniform sampler2DArray samplerDepth; + +layout (location = 0) in vec3 inUV; + +layout (location = 0) out vec4 outFragColor; + +float LinearizeDepth(float depth) +{ + float n = 1.0; // camera z near + float f = 96.0; // camera z far + float z = depth; + return (2.0 * n) / (f + n - z * (f - n)); +} + +void main() +{ + vec3 components[3]; + components[0] = texture(samplerPosition, inUV.st).rgb; + components[1] = texture(samplerNormal, inUV.st).rgb; + //components[2] = texture(samplerDepth, inUV.st).rgb; + // Uncomment to display specular component + //components[2] = vec3(texture(samplerAlbedo, inUV.st).a); + + // Select component depending on z coordinate of quad + highp int index = int(inUV.z); + if (index == 2) + { + float depth = texture(samplerDepth, vec3(inUV.st, 0.0)).r; + outFragColor = vec4(vec3(1.0-LinearizeDepth(depth)), 1.0); + } + else + { + outFragColor.rgb = components[index]; + } +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/debug.frag.spv b/data/shaders/deferredshadows/debug.frag.spv new file mode 100644 index 00000000..241d10fc Binary files /dev/null and b/data/shaders/deferredshadows/debug.frag.spv differ diff --git a/data/shaders/deferredshadows/debug.vert b/data/shaders/deferredshadows/debug.vert new file mode 100644 index 00000000..af5ced49 --- /dev/null +++ b/data/shaders/deferredshadows/debug.vert @@ -0,0 +1,27 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 3) in vec3 inNormal; + +layout (binding = 0) uniform UBO +{ + mat4 projection; + mat4 model; +} ubo; + +layout (location = 0) out vec3 outUV; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outUV = vec3(inUV.st, inNormal.z); + gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0); +} diff --git a/data/shaders/deferredshadows/debug.vert.spv b/data/shaders/deferredshadows/debug.vert.spv new file mode 100644 index 00000000..4300cf84 Binary files /dev/null and b/data/shaders/deferredshadows/debug.vert.spv differ diff --git a/data/shaders/deferredshadows/deferred.frag b/data/shaders/deferredshadows/deferred.frag new file mode 100644 index 00000000..1a9ee55d --- /dev/null +++ b/data/shaders/deferredshadows/deferred.frag @@ -0,0 +1,160 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (binding = 1) uniform sampler2D samplerposition; +layout (binding = 2) uniform sampler2D samplerNormal; +layout (binding = 3) uniform sampler2D samplerAlbedo; +// Depth from the light's point of view +//layout (binding = 5) uniform sampler2DShadow samplerShadowMap; +layout (binding = 5) uniform sampler2DArray samplerShadowMap; + +layout (location = 0) in vec2 inUV; + +layout (location = 0) out vec4 outFragColor; + +#define LIGHT_COUNT 3 +#define SHADOW_FACTOR 0.25 +#define AMBIENT_LIGHT 0.0 +#define USE_PCF + +struct Light +{ + vec4 position; + vec4 target; + vec4 color; + mat4 viewMatrix; +}; + +layout (binding = 4) uniform UBO +{ + vec4 viewPos; + Light lights[LIGHT_COUNT]; +} ubo; + +float textureProj(vec4 P, float layer, vec2 offset) +{ + float shadow = 1.0; + vec4 shadowCoord = P / P.w; + shadowCoord.st = shadowCoord.st * 0.5 + 0.5; + + if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0) + { + float dist = texture(samplerShadowMap, vec3(shadowCoord.st + offset, layer)).r; + if (shadowCoord.w > 0.0 && dist < shadowCoord.z) + { + shadow = SHADOW_FACTOR; + } + } + return shadow; +} + +float filterPCF(vec4 sc, float layer) +{ + ivec2 texDim = textureSize(samplerShadowMap, 0).xy; + float scale = 1.5; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + shadowFactor += textureProj(sc, layer, vec2(dx*x, dy*y)); + count++; + } + + } + return shadowFactor / count; +} + + +void main() +{ + // Get G-Buffer values + vec3 fragPos = texture(samplerposition, inUV).rgb; + vec3 normal = texture(samplerNormal, inUV).rgb; + vec4 albedo = texture(samplerAlbedo, inUV); + + // Ambient part + vec3 fragcolor = albedo.rgb * AMBIENT_LIGHT; + + vec3 N = normalize(normal); + + float shadow = 0.0; + + for(int i = 0; i < LIGHT_COUNT; ++i) + { + // Vector to light + vec3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + L = normalize(L); + + // Viewer to fragment + vec3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + float lightCosInnerAngle = cos(radians(15.0)); + float lightCosOuterAngle = cos(radians(25.0)); + float lightRange = 100.0; + + // Direction vector from source to target + vec3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz); + + // Dual cone spot light with smooth transition between inner and outer angle + float cosDir = dot(L, dir); + float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir); + float heightAttenuation = smoothstep(lightRange, 0.0f, dist); + + // Diffuse lighting. + float NdotL = max(0.0, dot(N, L)); + vec3 diff = /*ubo.lights[i].color.rgb * albedo.rgb */ vec3(NdotL); + + // Specular lighting. + vec3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + vec3 spec = /*ubo.lights[i].color.rgb * albedo.a */ vec3(pow(NdotR, 16.0)); + + vec4 shadowClip = ubo.lights[i].viewMatrix * vec4(fragPos, 1.0); + + float shadowFactor; + #ifdef USE_PCFA + shadowFactor= filterPCF(shadowClip, i); + #else + shadowFactor = textureProj(shadowClip, i, vec2(0.0)); + #endif + + //fragcolor += vec3(diff * spotEffect * heightAttenuation); + //fragcolor += vec3(diff * spotEffect * heightAttenuation) * shadowFactor * ubo.lights[i].color.rgb; + fragcolor += vec3(diff * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb; + + shadow += shadowFactor; + //if (shadowFactor > 0.5) + // fragcolor += vec3(0.25); + //else + // fragcolor += vec3(1.0-shadowFactor); + //fragcolor += (diff + spec) * spotEffect * heightAttenuation * shadowFactor; + } + + for(int i = 0; i < LIGHT_COUNT; ++i) + { + vec4 shadowClip = ubo.lights[i].viewMatrix * vec4(fragPos, 1.0); + + float shadowFactor; + #ifdef USE_PCF + shadowFactor= filterPCF(shadowClip, i); + #else + shadowFactor = textureProj(shadowClip, i, vec2(0.0)); + #endif + + fragcolor *= shadowFactor; + } + + outFragColor.rgb = fragcolor;// * shadow; +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/deferred.frag.spv b/data/shaders/deferredshadows/deferred.frag.spv new file mode 100644 index 00000000..5b3d628f Binary files /dev/null and b/data/shaders/deferredshadows/deferred.frag.spv differ diff --git a/data/shaders/deferredshadows/deferred.vert b/data/shaders/deferredshadows/deferred.vert new file mode 100644 index 00000000..b8926636 --- /dev/null +++ b/data/shaders/deferredshadows/deferred.vert @@ -0,0 +1,36 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec2 inUV; + +layout (binding = 0) uniform UBO +{ + mat4 projection; + mat4 modelview; + mat4 lightMVP; +} ubo; + +layout (location = 0) out vec2 outUV; +//layout (location = 1) out vec4 outShadowCoord; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +/* +const mat4 biasMat = mat4( + 0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.0, 1.0 ); + */ +void main() +{ + outUV = inUV; + gl_Position = ubo.projection * ubo.modelview * vec4(inPos.xyz, 1.0); + //outShadowCoord = (biasMat * ubo.lightMVP * ubo.modelview) * vec4(inPos, 1.0); +} diff --git a/data/shaders/deferredshadows/deferred.vert.spv b/data/shaders/deferredshadows/deferred.vert.spv new file mode 100644 index 00000000..bc47c34a Binary files /dev/null and b/data/shaders/deferredshadows/deferred.vert.spv differ diff --git a/data/shaders/deferredshadows/generate-spirv.bat b/data/shaders/deferredshadows/generate-spirv.bat new file mode 100644 index 00000000..9941aec7 --- /dev/null +++ b/data/shaders/deferredshadows/generate-spirv.bat @@ -0,0 +1,9 @@ +glslangvalidator -V debug.vert -o debug.vert.spv +glslangvalidator -V debug.frag -o debug.frag.spv +glslangvalidator -V mrt.vert -o mrt.vert.spv +glslangvalidator -V mrt.frag -o mrt.frag.spv +glslangvalidator -V shadow.vert -o shadow.vert.spv +glslangvalidator -V shadow.frag -o shadow.frag.spv +glslangvalidator -V shadow.geom -o shadow.geom.spv +glslangvalidator -V deferred.vert -o deferred.vert.spv +glslangvalidator -V deferred.frag -o deferred.frag.spv \ No newline at end of file diff --git a/data/shaders/deferredshadows/geom.spv b/data/shaders/deferredshadows/geom.spv new file mode 100644 index 00000000..0f7a0149 Binary files /dev/null and b/data/shaders/deferredshadows/geom.spv differ diff --git a/data/shaders/deferredshadows/mrt.frag b/data/shaders/deferredshadows/mrt.frag new file mode 100644 index 00000000..5a8f5436 --- /dev/null +++ b/data/shaders/deferredshadows/mrt.frag @@ -0,0 +1,33 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (binding = 1) uniform sampler2D samplerColor; +layout (binding = 2) uniform sampler2D samplerNormalMap; + +layout (location = 0) in vec3 inNormal; +layout (location = 1) in vec2 inUV; +layout (location = 2) in vec3 inColor; +layout (location = 3) in vec3 inWorldPos; +layout (location = 4) in vec3 inTangent; + +layout (location = 0) out vec4 outPosition; +layout (location = 1) out vec4 outNormal; +layout (location = 2) out vec4 outAlbedo; + +void main() +{ + outPosition = vec4(inWorldPos, 1.0); + + // Calculate normal in tangent space + vec3 N = normalize(inNormal); + N.y = -N.y; + vec3 T = normalize(inTangent); + vec3 B = cross(N, T); + mat3 TBN = mat3(T, B, N); + vec3 tnorm = TBN * normalize(texture(samplerNormalMap, inUV).xyz * 2.0 - vec3(1.0)); + outNormal = vec4(tnorm, 1.0); + + outAlbedo = texture(samplerColor, inUV); +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/mrt.frag.spv b/data/shaders/deferredshadows/mrt.frag.spv new file mode 100644 index 00000000..129538fd Binary files /dev/null and b/data/shaders/deferredshadows/mrt.frag.spv differ diff --git a/data/shaders/deferredshadows/mrt.vert b/data/shaders/deferredshadows/mrt.vert new file mode 100644 index 00000000..a8d3ee02 --- /dev/null +++ b/data/shaders/deferredshadows/mrt.vert @@ -0,0 +1,50 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec4 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 2) in vec3 inColor; +layout (location = 3) in vec3 inNormal; +layout (location = 4) in vec3 inTangent; + +layout (binding = 0) uniform UBO +{ + mat4 projection; + mat4 model; + mat4 view; + vec4 instancePos[3]; +} ubo; + +layout (location = 0) out vec3 outNormal; +layout (location = 1) out vec2 outUV; +layout (location = 2) out vec3 outColor; +layout (location = 3) out vec3 outWorldPos; +layout (location = 4) out vec3 outTangent; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + vec4 tmpPos = inPos + ubo.instancePos[gl_InstanceIndex]; + + gl_Position = ubo.projection * ubo.view * ubo.model * tmpPos; + + outUV = inUV; + outUV.t = 1.0 - outUV.t; + + // Vertex position in world space + outWorldPos = vec3(ubo.model * tmpPos); + + // Normal in world space + mat3 mNormal = transpose(inverse(mat3(ubo.model))); + outNormal = mNormal * normalize(inNormal); + outTangent = mNormal * normalize(inTangent); + + // Currently just vertex color + outColor = inColor; +} diff --git a/data/shaders/deferredshadows/mrt.vert.spv b/data/shaders/deferredshadows/mrt.vert.spv new file mode 100644 index 00000000..aaa4e3ff Binary files /dev/null and b/data/shaders/deferredshadows/mrt.vert.spv differ diff --git a/data/shaders/deferredshadows/shadow.frag b/data/shaders/deferredshadows/shadow.frag new file mode 100644 index 00000000..c1ff92b2 --- /dev/null +++ b/data/shaders/deferredshadows/shadow.frag @@ -0,0 +1,11 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout(location = 0) out float fragmentdepth; + +void main() +{ + fragmentdepth = gl_FragCoord.z; +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/shadow.frag.spv b/data/shaders/deferredshadows/shadow.frag.spv new file mode 100644 index 00000000..b5fdaaef Binary files /dev/null and b/data/shaders/deferredshadows/shadow.frag.spv differ diff --git a/data/shaders/deferredshadows/shadow.geom b/data/shaders/deferredshadows/shadow.geom new file mode 100644 index 00000000..04ca7d7e --- /dev/null +++ b/data/shaders/deferredshadows/shadow.geom @@ -0,0 +1,30 @@ +#version 420 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#define LIGHT_COUNT 3 + +layout (triangles, invocations = LIGHT_COUNT) in; +layout (triangle_strip, max_vertices = 3) out; + +layout (binding = 0) uniform UBO +{ + mat4 mvp[LIGHT_COUNT]; + vec4 instancePos[3]; +} ubo; + +layout (location = 0) in int inInstanceIndex[]; + +void main() +{ + vec4 instancedPos = ubo.instancePos[inInstanceIndex[0]]; + for (int i = 0; i < gl_in.length(); i++) + { + gl_Layer = gl_InvocationID; + vec4 tmpPos = gl_in[i].gl_Position + instancedPos; + gl_Position = ubo.mvp[gl_InvocationID] * tmpPos; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/shadow.geom.spv b/data/shaders/deferredshadows/shadow.geom.spv new file mode 100644 index 00000000..290cad98 Binary files /dev/null and b/data/shaders/deferredshadows/shadow.geom.spv differ diff --git a/data/shaders/deferredshadows/shadow.vert b/data/shaders/deferredshadows/shadow.vert new file mode 100644 index 00000000..61a60627 --- /dev/null +++ b/data/shaders/deferredshadows/shadow.vert @@ -0,0 +1,19 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec4 inPos; + +layout (location = 0) out int outInstanceIndex; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outInstanceIndex = gl_InstanceIndex; + gl_Position = inPos; +} \ No newline at end of file diff --git a/data/shaders/deferredshadows/shadow.vert.spv b/data/shaders/deferredshadows/shadow.vert.spv new file mode 100644 index 00000000..c3fc560e Binary files /dev/null and b/data/shaders/deferredshadows/shadow.vert.spv differ