SHADE_Y3/Assets/Shaders/DeferredComposite_CS.glsl

162 lines
5.0 KiB
Plaintext
Raw Normal View History

#version 450
struct DirectionalLightStruct
{
vec3 direction;
uint isActive;
uint cullingMask;
vec4 diffuseColor;
2023-01-07 17:45:49 +08:00
mat4 pvMatrix;
uint shadowData;
};
struct AmbientLightStruct
{
vec4 ambientColor;
float strength;
uint isActive;
uint cullingMask;
};
layout(local_size_x = 16, local_size_y = 16) in;
2022-12-28 20:47:20 +08:00
layout(set = 3, binding = 0, rgba32f) uniform image2D positions;
layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
2023-01-11 10:35:29 +08:00
layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace;
layout(set = 3, binding = 6, rgba8) uniform image2D targetImage;
layout(set = 3, binding = 7, rgba8) uniform image2D objectVFXImage;
2023-01-07 17:45:49 +08:00
layout (set = 4, binding = 0) uniform sampler2D shadowMaps[]; // for textures (global)
layout(set = 1, binding = 0) uniform LightCounts
{
uint directionalLights;
uint pointLights;
uint spotLights;
uint ambientLights;
} lightCounts;
layout(std430, set = 1, binding = 1) buffer DirectionalLightData
{
DirectionalLightStruct dLightData[];
} DirLightData;
layout(std430, set = 1, binding = 4) buffer AmbientLightData
{
AmbientLightStruct aLightData[];
} AmbLightData;
float LinStep (float val, float low, float high)
{
return clamp ((val - low)/(high - low), 0.0f, 1.0f);
}
2023-01-11 10:35:29 +08:00
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
{
// clip space for fragment from light view space
2023-01-11 10:35:29 +08:00
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
// Perform perspective division and convert to 0 to 1 range
2023-01-11 10:35:29 +08:00
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
2023-01-11 20:04:53 +08:00
// float sampledDepth = texture(shadowMap, converted.xy).r;
// float sampledDepth = texture(shadowMap, converted.xy).z;
vec2 moments = texture(shadowMap, converted.xy).xy;
2023-01-11 20:04:53 +08:00
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
return 1.0f;
if (fragPosLightPOV.z > moments.x && fragPosLightPOV.w > 0.0f)
2023-01-11 20:04:53 +08:00
{
float p = step (fragPosLightPOV.z, moments.x);
float variance = max (moments.y - (moments.x * moments.x), 0.00002f);
float d = fragPosLightPOV.z - moments.x;
float pMax = LinStep (variance / (variance + (d * d)), 0.9f, 1.0f);
return min (max (p, pMax), 1.0f);
2023-01-11 20:04:53 +08:00
}
else if (fragPosLightPOV.z > 1.0f)
{
return 0.0f;
}
2023-01-11 20:04:53 +08:00
else
return 0.3f;
2023-01-11 20:04:53 +08:00
// return step (fragPosLightPOV.z, );
2023-01-11 10:35:29 +08:00
}
2023-01-11 08:25:38 +08:00
void main()
{
// convenient variables
ivec2 globalThread = ivec2(gl_GlobalInvocationID);
// Get the diffuse color of the pixel
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
// Get position of fragment in world space
2023-01-11 10:35:29 +08:00
vec4 positionWorld = vec4 (imageLoad (positionWorldSpace, globalThread).rgb, 1.0f);
// Get position of fragment in view spacee
vec3 positionView = imageLoad (positions, globalThread).rgb;
// normal of fragment
2022-11-01 20:10:59 +08:00
vec3 normalView = imageLoad(normals, globalThread).rgb;
2022-11-02 14:21:27 +08:00
// light layer index
uint lightLayer = imageLoad (lightLayerData, globalThread).r;
vec3 fragColor = vec3 (0.0f);
vec4 shadowMapColor = vec4 (1.0f);
2023-01-11 08:25:38 +08:00
for (int i = 0; i < lightCounts.ambientLights; ++i)
{
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
{
// Just do some add
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
}
}
for (int i = 0; i < lightCounts.directionalLights; ++i)
{
2022-11-02 14:21:27 +08:00
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
{
// get normalized direction of light
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
2022-11-02 14:21:27 +08:00
// Get diffuse strength
float diffuseStrength = max (0, dot (-dLightNormalized, normalView));
2022-11-02 14:21:27 +08:00
// Calculate the fragment color
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
2023-01-11 08:25:38 +08:00
// If the shadow map is enabled (test the bit)
if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1)
{
// calculate shadow map here
2023-01-11 10:35:29 +08:00
fragColor *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix).xxx;
}
2022-11-02 14:21:27 +08:00
}
}
2022-11-01 20:10:59 +08:00
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
fragColor *= ssaoVal;
vec4 objectVFXColor = imageLoad (objectVFXImage, globalThread);
fragColor += objectVFXColor.rgb * objectVFXColor.a;
// store result into result image
2022-11-01 20:10:59 +08:00
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
2023-01-11 10:35:29 +08:00
// vec2 normTexCoords = vec2 (gl_GlobalInvocationID.xy) / vec2 (1024.0f);
// vec4 shadowMapVal = texture(shadowMaps[0], normTexCoords);
// if (normTexCoords.x > 1.0f || normTexCoords.y > 1.0f)
// shadowMapVal = vec4(0.0f);
// imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), shadowMapVal.xxxx);
}