Skip to content

Commit 52ac689

Browse files
committed
Tutorial 15 - Mapeo de Sombras
Utilización de FBO para almacenar un mapa de profundidad utilizado para generar sombras.
1 parent 15d4bc9 commit 52ac689

9 files changed

+323
-0
lines changed

Data/test.assbin

146 KB
Binary file not shown.

Tutorial-15/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
project(15-Sombras)
2+
3+
file(COPY shadows.vs.glsl shadows.fs.glsl shadow-map-debug.vs.glsl shadow-map-debug.fs.glsl shadow-map.vs.glsl shadow-map.fs.glsl DESTINATION shaders)
4+
file(COPY ../Data/test.assbin DESTINATION model)
5+
6+
set(ASSIMP_DIR $ENV{ASSIMP_DIR} CACHE PATH "Assimp Directory")
7+
8+
find_package(ASSIMP REQUIRED)
9+
10+
link_directories(${ASSIMP_LIBRARY_DIRS})
11+
include_directories(${ASSIMP_INCLUDE_DIRS})
12+
13+
add_executable( ${PROJECT_NAME} shadow-map.cpp
14+
shaders/shadow-map.fs.glsl
15+
shaders/shadow-map.vs.glsl
16+
shaders/shadow-map-debug.fs.glsl
17+
shaders/shadow-map-debug.vs.glsl
18+
shaders/shadows.fs.glsl
19+
shaders/shadows.vs.glsl
20+
../common/openglmodel.hpp
21+
../common/openglwindow.hpp
22+
../common/openglshader.hpp
23+
../common/openglcamera.hpp )
24+
25+
target_link_libraries( ${PROJECT_NAME} ${GRAPHIC_LIBS} ${ASSIMP_LIBRARIES})

Tutorial-15/shadow-map-debug.fs.glsl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 330 core
2+
3+
out vec4 color;
4+
5+
uniform sampler2D depthMap;
6+
7+
in vec2 UV;
8+
9+
void main(void)
10+
{
11+
float depth = texture(depthMap, UV).r;
12+
color = vec4(vec3(depth), 1.0);
13+
}

Tutorial-15/shadow-map-debug.vs.glsl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#version 330 core
2+
3+
layout (location = 0) in vec3 position;
4+
layout (location = 1) in vec2 texture;
5+
6+
out vec2 UV;
7+
8+
void main(void)
9+
{
10+
gl_Position = vec4(position, 1.0);
11+
UV = texture;
12+
}

Tutorial-15/shadow-map.cpp

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#include "OpenGLWindow.hpp"
2+
#include "OpenGLShader.hpp"
3+
#include "OpenGLCamera.hpp"
4+
#include "OpenGLModel.hpp"
5+
6+
#include <glm\gtc\matrix_inverse.hpp>
7+
#include <glm\gtc\matrix_transform.hpp>
8+
#include <glm\gtc\type_ptr.hpp>
9+
10+
#include <string>
11+
12+
class Tutorial_OpenGL_Moderno : public OpenGLWindow {
13+
14+
public:
15+
Tutorial_OpenGL_Moderno() { }
16+
17+
private:
18+
void onstart() override {
19+
glEnable(GL_DEPTH_TEST);
20+
21+
glClearDepth(1.0f);
22+
glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
23+
24+
camera.setWindow(this->window);
25+
26+
light_shadow_shader.compile("shaders/shadows.vs.glsl", "shaders/shadows.fs.glsl");
27+
shadow_shader.compile("shaders/shadow-map.vs.glsl", "shaders/shadow-map.fs.glsl");
28+
debug_shader.compile("shaders/shadow-map-debug.vs.glsl", "shaders/shadow-map-debug.fs.glsl");
29+
30+
model.init("model/test.assbin");
31+
32+
createShadowMap();
33+
34+
// ocultar el cursor y ubicarlo en el centro de la ventana
35+
glfwSetInputMode(this->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
36+
glfwSetCursorPos(this->window, 1280 / 2, 720 / 2);
37+
}
38+
39+
void createShadowMap() {
40+
glGenTextures(1, &shadowMapTexID);
41+
glBindTexture(GL_TEXTURE_2D, shadowMapTexID);
42+
43+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
44+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
45+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
46+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
47+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
48+
49+
static GLfloat border[4] = { 1, 0, 0, 0 };
50+
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
51+
52+
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
53+
glGenFramebuffers(1, &fboID);
54+
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
55+
56+
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMapTexID, 0);
57+
58+
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
59+
cout << "Error al inicializar FBO." << endl;
60+
}
61+
62+
glDrawBuffer(GL_NONE);
63+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
64+
}
65+
66+
void onrender(double time) override {
67+
68+
if (showDepthMap) glDisable(GL_CULL_FACE);
69+
else glEnable(GL_CULL_FACE);
70+
71+
shadow_shader.use();
72+
73+
float X = sin(static_cast<float>(time)) * 10.0f;
74+
float Z = cos(static_cast<float>(time)) * 10.0f;
75+
76+
glm::vec3 lightPosOS(X, 8.0f, Z);
77+
78+
glm::mat4 P_L = glm::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
79+
glm::mat4 MV_L = glm::lookAt(lightPosOS, glm::vec3(0), glm::vec3(0, 1, 0));
80+
81+
glUniformMatrix4fv(shadow_shader.getUniformLocation("MVP"), 1, GL_FALSE, glm::value_ptr(P_L * MV_L));
82+
83+
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
84+
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
85+
glClear(GL_DEPTH_BUFFER_BIT);
86+
glCullFace(GL_FRONT);
87+
glEnable(GL_POLYGON_OFFSET_FILL);
88+
glPolygonOffset(1.0f, 1.0f);
89+
90+
model.draw();
91+
92+
glDisable(GL_POLYGON_OFFSET_FILL);
93+
glCullFace(GL_BACK);
94+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
95+
96+
shadow_shader.unUse();
97+
98+
99+
// Restablecer viewport para dibujar de modo normal
100+
glViewport(0, 0, 1280, 720);
101+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102+
103+
// Visualizar mapa de profundidad
104+
if (showDepthMap) {
105+
debug_shader.use();
106+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
107+
RenderQuad();
108+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
109+
debug_shader.unUse();
110+
}
111+
112+
light_shadow_shader.use();
113+
114+
glm::mat4 B(0.5, 0.0, 0.0, 0.0,
115+
0.0, 0.5, 0.0, 0.0,
116+
0.0, 0.0, 0.5, 0.0,
117+
0.5, 0.5, 0.5, 1.0);
118+
119+
glm::mat4 S = B * P_L * MV_L;
120+
121+
glm::mat4 M = glm::mat4(1);
122+
glm::mat4 MV = camera.getViewMatrix() * M;
123+
glm::mat4 MVP = camera.getProjectionMatrix() * MV;
124+
glm::mat3 N = glm::inverseTranspose(glm::mat3(MV));
125+
126+
glUniformMatrix4fv(light_shadow_shader.getUniformLocation("MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
127+
glUniformMatrix4fv(light_shadow_shader.getUniformLocation("MV"), 1, GL_FALSE, glm::value_ptr(MV));
128+
glUniformMatrix4fv(light_shadow_shader.getUniformLocation("M"), 1, GL_FALSE, glm::value_ptr(M));
129+
glUniformMatrix4fv(light_shadow_shader.getUniformLocation("S"), 1, GL_FALSE, glm::value_ptr(S));
130+
glUniformMatrix3fv(light_shadow_shader.getUniformLocation("N"), 1, GL_FALSE, glm::value_ptr(N));
131+
132+
glm::vec3 lightPosES = glm::vec3(MV * glm::vec4(lightPosOS, 0));
133+
134+
glUniform3fv(light_shadow_shader.getUniformLocation("light_position"), 1, glm::value_ptr(lightPosES));
135+
glUniform3fv(light_shadow_shader.getUniformLocation("diffuse_color"), 1, glm::value_ptr(glm::vec3(0.75f)));
136+
137+
model.draw();
138+
139+
light_shadow_shader.unUse();
140+
141+
}
142+
143+
GLuint quadVAO = 0;
144+
GLuint quadVBO;
145+
void RenderQuad()
146+
{
147+
if (quadVAO == 0)
148+
{
149+
GLfloat quadVertices[] = {
150+
// Positions // Texture Coords
151+
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
152+
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
153+
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
154+
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
155+
};
156+
157+
glGenVertexArrays(1, &quadVAO);
158+
glGenBuffers(1, &quadVBO);
159+
glBindVertexArray(quadVAO);
160+
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
161+
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
162+
glEnableVertexAttribArray(0);
163+
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
164+
glEnableVertexAttribArray(1);
165+
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
166+
}
167+
168+
glBindVertexArray(quadVAO);
169+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
170+
glBindVertexArray(0);
171+
}
172+
173+
void onkey(int key, int scancode, int action, int mods) override {
174+
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
175+
glfwSetWindowShouldClose(window, GL_TRUE);
176+
177+
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
178+
showDepthMap = !showDepthMap;
179+
}
180+
181+
Model model;
182+
OpenGLShader light_shadow_shader, shadow_shader, debug_shader;
183+
OpenGLCamera camera;
184+
185+
const GLsizei SHADOW_MAP_SIZE = 1024 * 2;
186+
187+
GLuint shadowMapTexID, fboID;
188+
GLuint vao, index_buffer;
189+
GLuint buffer[2];
190+
191+
bool showDepthMap = false;
192+
};
193+
194+
int main() {
195+
Tutorial_OpenGL_Moderno win_app;
196+
197+
if (win_app.init("OpenGL Moderno - Shadow Maps", 1280, 720)) {
198+
win_app.info();
199+
200+
cout << "TOTURIALES OPENGL MODERNO - SHADOW MAP" << endl << endl;
201+
cout << "Presione la tecla [SPACE] para (mostrar/ocultar) el depth map." << endl;
202+
cout << "Usar la tecla [Esc] para salir." << endl << endl;
203+
204+
win_app.run();
205+
}
206+
207+
return 0;
208+
}

Tutorial-15/shadow-map.fs.glsl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#version 330 core
2+
3+
layout (location = 0) out vec4 color;
4+
5+
void main(void)
6+
{
7+
color = vec4(1.0);
8+
}

Tutorial-15/shadow-map.vs.glsl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#version 330 core
2+
3+
uniform mat4 MVP;
4+
5+
layout (location = 0) in vec3 position;
6+
7+
void main(void)
8+
{
9+
gl_Position = MVP * vec4(position, 1.0);
10+
}

Tutorial-15/shadows.fs.glsl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#version 330 core
2+
3+
out vec4 color;
4+
5+
uniform sampler2DShadow shadowMap;
6+
7+
uniform vec3 light_position;
8+
uniform vec3 diffuse_color;
9+
10+
in vec3 NORMAL;
11+
in vec3 POSITION;
12+
in vec4 SHADOW;
13+
14+
void main() {
15+
vec3 L = normalize(light_position - POSITION);
16+
17+
float diffuse = max(0, dot(NORMAL, L));
18+
19+
if(SHADOW.w > 1) {
20+
float shadow = textureProj(shadowMap, SHADOW);
21+
diffuse = mix(diffuse, diffuse * shadow, 0.5);
22+
}
23+
24+
color = diffuse * vec4(diffuse_color, 1);
25+
}

Tutorial-15/shadows.vs.glsl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#version 330 core
2+
3+
layout(location=0) in vec3 position;
4+
layout(location=2) in vec3 normal;
5+
6+
uniform mat4 MVP; //modelview projection matrix
7+
uniform mat4 MV; //modelview matrix
8+
uniform mat4 M; //model matrix
9+
uniform mat3 N; //normal matrix
10+
uniform mat4 S; //shadow matrix
11+
12+
out vec3 NORMAL;
13+
out vec3 POSITION;
14+
out vec4 SHADOW;
15+
16+
void main()
17+
{
18+
POSITION = (MV * vec4(position, 1.0)).xyz;
19+
NORMAL = N * normal;
20+
SHADOW = S * (M * vec4(position, 1.0));
21+
gl_Position = MVP * vec4(position, 1.0);
22+
}

0 commit comments

Comments
 (0)