diff --git a/shaders/point_shadow.frag b/shaders/point_shadow.frag new file mode 100644 index 0000000..32b41d8 --- /dev/null +++ b/shaders/point_shadow.frag @@ -0,0 +1,17 @@ +#version 330 core + +in vec4 FragPos; +in vec3 lightPos; +in float radius; + +void main() +{ + // Расстояние между источником и фрагментом + float lightDistance = length(FragPos.xyz - lightPos); + + // Приведение к диапазону [0;1] + lightDistance = lightDistance / radius; + + // Замена значения глубины + gl_FragDepth = lightDistance; +} \ No newline at end of file diff --git a/shaders/point_shadow.geom b/shaders/point_shadow.geom new file mode 100644 index 0000000..c6e8115 --- /dev/null +++ b/shaders/point_shadow.geom @@ -0,0 +1,38 @@ +#version 420 core +layout (triangles, invocations = 6) in; // здесь invocations соответствует числу сторон кубической карты теней +layout (triangle_strip, max_vertices=18) out; // здесь max_vertices = 3 вершины * 6 вызовов на стороны куба + +struct LightData +{ + vec3 position; + vec3 color; + vec3 attenuation; + vec4 direction_angle; + mat4 vp[6]; +}; + +layout(std140, binding = 2) uniform Light +{ + LightData data[64]; + int count; +} light_g; + +uniform int light_i; + +out vec4 FragPos; +out vec3 lightPos; +out float radius; + +void main() +{ + for(int i = 0; i < 3; ++i) + { + FragPos = gl_in[i].gl_Position; + lightPos = light_g.data[light_i].position; + radius = light_g.data[light_i].attenuation.r; + gl_Position = light_g.data[light_i].vp[gl_InvocationID] * gl_in[i].gl_Position; + gl_Layer = gl_InvocationID + light_i*6; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 48b29d3..06ef1bb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -234,6 +234,14 @@ int main(void) // Активируем базовый буфер кадра FBO::useDefault(); + // Шейдер для расчета теней от точечных источников + ShaderProgram pointShadowShader; + // Загрузим шейдер + pointShadowShader.load(GL_VERTEX_SHADER, "shaders/sun_shadow.vert"); + pointShadowShader.load(GL_GEOMETRY_SHADER, "shaders/point_shadow.geom"); + pointShadowShader.load(GL_FRAGMENT_SHADER, "shaders/point_shadow.frag"); + pointShadowShader.link(); + // Модель прямоугольника Model rectangle;