ShadowPass.vert
Код: Выделить всё
#version 120
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Код: Выделить всё
#version 120
uniform float near_plane;
uniform float far_plane;
void main()
{
float z = gl_FragCoord.z;
float n = near_plane;
float f = far_plane;
float c = (2.0 * n) / (f + n - z * (f - n));
gl_FragDepth = c;
}
Код: Выделить всё
#version 120
varying vec3 position;
varying vec3 normal;
varying vec3 FragPos;
varying vec4 FragPosLightSpace;
uniform mat4 lightSpaceMatrix;
void main()
{
vec4 eyeCoordPos = gl_ModelViewMatrix * gl_Vertex;
position = eyeCoordPos.xyz / eyeCoordPos.w;
normal = normalize(gl_NormalMatrix * gl_Normal);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
FragPos = gl_Vertex.xyz;
FragPosLightSpace = lightSpaceMatrix * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Код: Выделить всё
#version 120
#define USE_INNER_AND_OUTER_CONES
#if defined(USE_INNER_AND_OUTER_CONES)
uniform float cosOuterCone;
uniform float cosInnerCone;
#endif
varying vec3 position;
varying vec3 normal;
uniform bool computeShadows;
uniform sampler2D colorMap;
uniform sampler2D shadowMap;
uniform vec3 lightPos;
varying vec3 FragPos;
varying vec4 FragPosLightSpace;
vec4 ShadowCalculation()
{
vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5; // Bias Matrix...
float closestDepth = texture2D(shadowMap, projCoords.xy).r;
float z = projCoords.z;
float n = 1.0;
float f = 1000.0;
float currentDepth = (2.0 * n) / (f + n - z * (f - n));
vec3 shadow = vec3(1.0, 1.0, 1.0);
float bias = 0.0005;
if(closestDepth + bias < currentDepth)
{
shadow = vec3(0.5, 0.5, 0.5); // Shadow color
}
return vec4(shadow, 1.0);
}
void main()
{
vec3 l = gl_LightSource[0].position.xyz - position;
float d = length(l);
float atten = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * d +
gl_LightSource[0].quadraticAttenuation * d * d);
l = normalize(l);
float spotDot = dot(-l, normalize(gl_LightSource[0].spotDirection));
#if defined(USE_INNER_AND_OUTER_CONES)
float spotEffect = smoothstep(cosOuterCone, cosInnerCone, spotDot);
#else
float spotEffect = (spotDot < gl_LightSource[0].spotCosCutoff)
? 0.0 : pow(spotDot, gl_LightSource[0].spotExponent);
#endif
atten *= spotEffect;
vec3 n = normalize(normal);
vec3 v = normalize(-position);
vec3 h = normalize(l + v);
float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);
vec4 ambient = gl_FrontLightProduct[0].ambient * atten;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL * atten;
vec4 specular = gl_FrontLightProduct[0].specular * power * atten;
vec4 lightColor = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;
vec4 finalColor = vec4(0);
if (computeShadows)
{
vec4 shadow = ShadowCalculation();
finalColor = shadow * texture2D(colorMap, gl_TexCoord[0].st) * lightColor;
}
else
{
finalColor = lightColor * texture2D(colorMap, gl_TexCoord[0].st);
}
gl_FragColor = finalColor;
}
Код: Выделить всё
glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT);
pShaderMgr->bind(0);
glUniform1f(glGetUniformLocation(pShaderMgr->id(0), "near_plane"), near_plane);
glUniform1f(glGetUniformLocation(pShaderMgr->id(0), "far_plane"), far_plane);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45.0f, static_cast(SHADOW_WIDTH) / static_cast(SHADOW_HEIGHT), near_plane, far_plane);
//glOrtho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
// OR
lightProjection = glm::perspective(glm::radians(45.0f), static_cast(SHADOW_WIDTH) / static_cast(SHADOW_HEIGHT), near_plane, far_plane);
//lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
glLoadMatrixf((float*)&lightProjection);
//glGetFloatv(GL_PROJECTION_MATRIX, (float*)&lightProjection);
lightView = glm::lookAt(glm::vec3(LightPosition[0], LightPosition[1], LightPosition[2]),
glm::vec3(LightDirection[0], LightDirection[1], LightDirection[2]),
glm::vec3(0.0, 1.0, 0.0));
lightSpaceMatrix = /*biasMatrix*/ lightProjection * lightView;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf((float*)&lightView);
glPushMatrix();
glTranslatef(0.0f, 1.0f, 0.0f);
DrawCubeVBO();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.0f, 4.0f, 1.0f);
DrawCubeVBO();
glPopMatrix();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
pShaderMgr->unbind();
/////////////////////////////////// COLOR BUFFER /////////////////////////////////////////////////////////
glViewport(0, 0, WIDTH, HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Limpa a tela e o Depth Buffer
glLoadIdentity(); // Inicializa a Modelview Matrix Atual
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(45.0f, static_cast(WIDTH) / static_cast(HEIGHT), near_plane, far_plane);
// OR
glm::mat4 camProjection = glm::perspective(glm::radians(45.0f), static_cast(WIDTH) / static_cast(HEIGHT), near_plane, far_plane);
glLoadMatrixf((float*)&camProjection);
pCamera->setView();
// Desenha os eixos do sistema cartesiano
DrawAxis();
// Modo FILL ou WIREFRAME (pressione barra de espaço)
if (bIsWireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DESENHA OS OBJETOS DA CENA (INÍCIO)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
pShaderMgr->bind(1);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "colorMap"), 0);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "shadowMap"), 1);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "computeShadows"), true);
glUniform1f(glGetUniformLocation(pShaderMgr->id(1), "cosInnerCone"), g_cosInnerCone);
glUniform1f(glGetUniformLocation(pShaderMgr->id(1), "cosOuterCone"), g_cosOuterCone);
glUniform3f(glGetUniformLocation(pShaderMgr->id(1), "lightPos"), LightPosition[0], LightPosition[1], LightPosition[2]);
glUniformMatrix4fv(glGetUniformLocation(pShaderMgr->id(1), "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
// Setup lighting and shaders.
glPushAttrib(GL_LIGHTING_BIT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, SPOT_OUTER_CONE);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0f);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, LightDirection);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
pTextures->ApplyTexture(0);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, shadowMap);
// Draw Cubes
glPushMatrix();
glTranslatef(0.0f, 1.0f, 0.0f);
DrawCubeVBO();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.0f, 4.0f, 1.0f);
DrawCubeVBO();
glPopMatrix();
// Draw Ground
glActiveTexture(GL_TEXTURE0);
pTextures->ApplyTexture(2);
glUniform1i(glGetUniformLocation(pShaderMgr->id(1), "computeShadows"), true);
glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2d(0.0f, 0.0f); glVertex3f(-20.0f, 0.0f, 20.0f);
glTexCoord2d(0.0f, 1.0f); glVertex3f(20.0f, 0.0f, 20.0f);
glTexCoord2d(1.0f, 1.0f); glVertex3f(20.0f, 0.0f, -20.0f);
glTexCoord2d(1.0f, 0.0f); glVertex3f(-20.0f, 0.0f, -20.0f);
glEnd();
glPopMatrix();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
pShaderMgr->unbind();
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glPopAttrib();

< /p>
Тень отображается неправильно. Похоже, что это повторяется в объектах.
Я считаю, что это проблема при рендеринге кубов в функции рендеринга. Кто-нибудь может подсказать, почему на кубиках не правильно рассчитываются тени? Верх кубиков должен быть на свету...
Подробнее здесь: https://stackoverflow.com/questions/781 ... -behaviour