diff --git a/shaders/lighting.frag b/shaders/lighting.frag index 20d67a8..91e2924 100644 --- a/shaders/lighting.frag +++ b/shaders/lighting.frag @@ -27,12 +27,14 @@ layout(std140, binding = 3) uniform Sun { vec3 direction; vec3 color; + mat4 vp; } sun; uniform sampler2D gPosition; uniform sampler2D gNormal; uniform sampler2D gDiffuseP; uniform sampler2D gAmbientSpecular; +uniform sampler2D sunShadowDepth; out vec4 color; @@ -56,25 +58,40 @@ void main() float attenuation; // Коэф. угасания float acosA; // Косинус между вектором от поверхности к источнику и обратным направлением источника float intensity; // Интенсивность для прожектора + vec3 fragPosLightSpace; // Фрагмент в пространстве источника + float closestDepth; // Значение глубины из буфера тени + float shadowValue; // Значение затененности // Фоновая освещенность color = vec4(ka, 1); - + // Расчет солнца, если его цвет не черный if (length(sun.color) > 0) { - // Данные об источнике относительно фрагмента - L_vertex = normalize(sun.direction); - // Диффузная составляющая - diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0 - - // Вектор половины пути - H = normalize(L_vertex + Cam_vertex); - // Зеркальная составляющая - specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p - // Результирующий цвет с учетом солнца - color += vec4(sun.color*kd*diffuse, 1) - + vec4(sun.color*ks*specular, 1); + // Расположение фрагмента в координатах теневой карты + fragPosLightSpace = (sun.vp * vec4(fragPos, 1.0)).xyz; + // Переход от [-1;1] к [0;1] + fragPosLightSpace = (fragPosLightSpace + vec3(1.0)) / 2; + // Получим значение ближайшей глубины к источнику + closestDepth = texture(sunShadowDepth, fragPosLightSpace.xy).r; + // Проверим, что рассматриваемый фрагмент ближе чем значение глубины + shadowValue = fragPosLightSpace.z > closestDepth ? 1.0 : 0.0; + // Рассчитываем освещенность, если значение тени меньше 1 + if (shadowValue < 1.0) + { + // Данные об источнике относительно фрагмента + L_vertex = normalize(sun.direction); + // Диффузная составляющая + diffuse = max(dot(L_vertex, N), 0.0); // скалярное произведение с отсеканием значений < 0 + + // Вектор половины пути + H = normalize(L_vertex + Cam_vertex); + // Зеркальная составляющая + specular = pow(max(dot(H, N), 0.0), p*4); // скалярное произведение с отсеканием значений < 0 в степени p + // Результирующий цвет с учетом солнца + color += vec4(sun.color*kd*diffuse, 1) + + vec4(sun.color*ks*specular, 1); + } } // Цикл по источникам света