// XC_BUILTIN_FORWARD_LIT_VULKAN_PS #version 450 layout(set = 3, binding = 0) uniform texture2D uBaseColorTexture; layout(set = 4, binding = 0) uniform sampler uLinearSampler; layout(set = 6, binding = 0) uniform texture2D uShadowMapTexture; layout(set = 7, binding = 0) uniform sampler uShadowMapSampler; layout(set = 1, binding = 0, std140) uniform PerObjectConstants { mat4 gProjectionMatrix; mat4 gViewMatrix; mat4 gModelMatrix; mat4 gNormalMatrix; vec4 gMainLightDirectionAndIntensity; vec4 gMainLightColorAndFlags; }; layout(set = 2, binding = 0, std140) uniform MaterialConstants { vec4 gBaseColorFactor; }; layout(set = 5, binding = 0, std140) uniform ShadowReceiverConstants { mat4 gWorldToShadowMatrix; vec4 gShadowBiasAndTexelSize; vec4 gShadowOptions; }; layout(location = 0) in vec3 vNormalWS; layout(location = 1) in vec2 vTexCoord; layout(location = 2) in vec3 vPositionWS; layout(location = 0) out vec4 fragColor; float ComputeShadowAttenuation(vec3 positionWS) { if (gShadowOptions.x < 0.5) { return 1.0; } vec4 shadowClip = gWorldToShadowMatrix * vec4(positionWS, 1.0); if (shadowClip.w <= 0.0) { return 1.0; } vec3 shadowNdc = shadowClip.xyz / shadowClip.w; vec2 shadowUv = vec2( shadowNdc.x * 0.5 + 0.5, shadowNdc.y * -0.5 + 0.5); if (shadowUv.x < 0.0 || shadowUv.x > 1.0 || shadowUv.y < 0.0 || shadowUv.y > 1.0 || shadowNdc.z < 0.0 || shadowNdc.z > 1.0) { return 1.0; } float shadowDepth = texture(sampler2D(uShadowMapTexture, uShadowMapSampler), shadowUv).r; float receiverDepth = shadowNdc.z - gShadowBiasAndTexelSize.x; float shadowStrength = clamp(gShadowBiasAndTexelSize.w, 0.0, 1.0); return receiverDepth <= shadowDepth ? 1.0 : (1.0 - shadowStrength); } void main() { vec4 baseColor = texture(sampler2D(uBaseColorTexture, uLinearSampler), vTexCoord) * gBaseColorFactor; if (gMainLightColorAndFlags.w < 0.5) { fragColor = baseColor; return; } vec3 normalWS = normalize(vNormalWS); vec3 directionToLightWS = normalize(gMainLightDirectionAndIntensity.xyz); float diffuse = max(dot(normalWS, directionToLightWS), 0.0); float shadowAttenuation = diffuse > 0.0 ? ComputeShadowAttenuation(vPositionWS) : 1.0; vec3 lighting = vec3(0.28) + gMainLightColorAndFlags.rgb * (diffuse * gMainLightDirectionAndIntensity.w * shadowAttenuation); fragColor = vec4(baseColor.rgb * lighting, baseColor.a); }