#version 120 uniform bool shadows_enabled; uniform mat4 fg_LightMatrix_csm0; uniform mat4 fg_LightMatrix_csm1; uniform mat4 fg_LightMatrix_csm2; uniform mat4 fg_LightMatrix_csm3; varying vec4 lightSpacePos[4]; const float NORMAL_OFFSET_SCALES[4] = float[4](0.0, 0.1, 0.3, 1.0); void setupShadows(vec4 eyeSpacePos) { if (!shadows_enabled) return; vec3 normal = gl_NormalMatrix * gl_Normal; vec3 toLight = normalize(gl_LightSource[0].position.xyz); float costheta = dot(normal, toLight); float slopeScale = clamp(1.0 - costheta, 0.0, 1.0); vec4 offsetPos[4]; for (int i = 0; i < 4; i++) { float normalOffset = NORMAL_OFFSET_SCALES[i] * slopeScale; offsetPos[i] = eyeSpacePos + vec4(normal * normalOffset, 0.0); } vec4 offsetPosLightSpace[4]; offsetPosLightSpace[0] = fg_LightMatrix_csm0 * offsetPos[0]; offsetPosLightSpace[1] = fg_LightMatrix_csm1 * offsetPos[1]; offsetPosLightSpace[2] = fg_LightMatrix_csm2 * offsetPos[2]; offsetPosLightSpace[3] = fg_LightMatrix_csm3 * offsetPos[3]; lightSpacePos[0] = fg_LightMatrix_csm0 * eyeSpacePos; lightSpacePos[1] = fg_LightMatrix_csm1 * eyeSpacePos; lightSpacePos[2] = fg_LightMatrix_csm2 * eyeSpacePos; lightSpacePos[3] = fg_LightMatrix_csm3 * eyeSpacePos; // Offset only in UV space for (int i = 0; i < 4; i++) lightSpacePos[i].xy = offsetPosLightSpace[i].xy; }