From 254dbdd90ef6bfa443022e425d33a631890f8e0d Mon Sep 17 00:00:00 2001 From: "re.kovalev" Date: Fri, 3 Nov 2023 13:57:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A8=D0=B5=D0=B9=D0=B4=D0=B5=D1=80=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B5=D0=BD=D0=B5=D0=B9=20=D0=BE?= =?UTF-8?q?=D1=82=20=D1=82=D0=BE=D1=87=D0=B5=D1=87=D0=BD=D1=8B=D1=85=20?= =?UTF-8?q?=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shaders/point_shadow.frag | 17 +++++++++++++++++ shaders/point_shadow.geom | 38 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 8 ++++++++ 3 files changed, 63 insertions(+) create mode 100644 shaders/point_shadow.frag create mode 100644 shaders/point_shadow.geom 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;