我设法只向一个方向执行阴影映射,这意味着我创建了2D纹理深度图。现在使用全向阴影贴图,我遇到了一些麻烦。这是我的代码的主要部分:
首先渲染-创建立方体贴图
glUseProgram(cubeShader);
glViewport(0, 0, 1024, 1024);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMap, 0);
mat4 modelMatrix = mat4(1);
glUniform3f(lightLocationCube, lightPos.x, lightPos.y, lightPos.z);
glUniform1f(farPlaneCubeLoc, 25.0f);
mat4 shadowProj = perspective(double(radians(90.0f)), 4.0 / 4.0, 1.0, 10.0);
lightTransforms.clear();
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
lightTransforms.push_back(shadowProj *
glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
for (int i = 0; i < 6; ++i) {
mat4 nowT = lightTransforms[i];
glUniformMatrix4fv(shadowMatricesCubeLoc[i], 1, GL_FALSE, &nowT[0][0]);
}
glBindVertexArray(objVAO);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
modelMatrix *= translate(mat4(), vec3(0, 0, 5))*rotate(mat4(), 3.14f, vec3(0, 1, 0));
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
// Drawing a cube
glBindVertexArray(planeVAO);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
modelMatrix = scale(mat4(), vec3(10, 10, 0));
modelMatrix = rotate(mat4(), radians(0.0f), vec3(0, 1, 0));
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
modelMatrix = scale(mat4(), vec3(10, 10, 0));
modelMatrix = rotate(mat4(), radians(90.0f), vec3(0, 1, 0));
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
modelMatrix = scale(mat4(), vec3(10, 10, 0));
modelMatrix = rotate(mat4(), radians(180.0f), vec3(0, 1, 0));
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
modelMatrix = scale(mat4(), vec3(10, 10, 0));
modelMatrix = rotate(mat4(), radians(270.0f), vec3(0, 1, 0));
glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
之前,我已经为多维数据集映射完成了相对的“声明”(如果我使用正确的词):
glGenFramebuffers(1, &depthCubeMapFBO);
glGenTextures(1, &depthCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubeMap);
for (unsigned int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//CubeMapLocs
lightLocationCube = glGetUniformLocation(cubeShader, "lightPos");
modelMatrixCubeLoc = glGetUniformLocation(cubeShader, "M");
farPlaneCubeLoc = glGetUniformLocation(cubeShader, "far_plane");
for (int i = 0; i < 6; i++) {
string added = "shadowMatrices[" + std::to_string(i) + "]";
shadowMatricesCubeLoc[i] = glGetUniformLocation(cubeShader, added.c_str());
}
现在,我将不会在第二个渲染循环中包含所有内容,因为您可能会看到一些奇怪的东西,它会很长,但这是我将纹理发送到着色器的地方:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
glUniform1i(diffuceColorSampler, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularTexture);
glUniform1i(specularColorSampler, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_CUBE_MAP , depthCubeMap);
glUniform1i(shadowMapLoc, 2);
我正在为此循环使用第二个着色器,现在我将把所有内容都包含在两个着色器中
第一循环顶点着色器:
#version 330 core
uniform mat4 M;
layout(location = 0) in vec3 vertexPosition_modelspace;
void main()
{
gl_Position=M*vec4(vertexPosition_modelspace,1.0);
}
第一循环几何着色器:
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;
uniform mat4 shadowMatrices[6];
out vec4 FragPos;
void main()
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face;
for(int i = 0; i < 3; ++i)
{
FragPos = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPos;
EmitVertex();
}
EndPrimitive();
}
}
第一循环片段着色器
#version 330 core
in vec4 FragPos;
uniform vec3 lightPos;
uniform int far_plane;
void main()
{
// get distance between fragment and light source
float lightDistance = length(FragPos.xyz - lightPos);
// map to [0;1] range by dividing by far_plane
lightDistance = lightDistance / 25.0;
// write this as modified depth
gl_FragDepth = lightDistance;
//col=gl_FragDepth*vec4(1,1,1,1);
//col.w=1;
//col=vec4(0.5,0,1.0,1.0);
//fragment_color = vec4(vec3(closestDepth / 25.0), 1.0);
}
第二循环顶点着色器
#version 330 core
// construct input layout for the corresponding attributes
// (vertexPosition_modelspace, vertexNormal_modelspace, vertexUV)
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexNormal_modelspace;
layout(location = 2) in vec2 vertexUV;
// Output variables (position_modelspace, normal_modelspace and UV coordinates),
// that will be interpolated for each fragment
out vec3 vertex_position_modelspace;
out vec3 vertex_normal_modelspace;
out vec2 vertex_UV;
out vec3 vertexWorldspace;
// uniforms (P, V, M)
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
uniform mat4 lightSpaceTransform;
out vec4 vertex_LightSpace;
void main()
{
vertex_LightSpace=lightSpaceTransform*M*vec4(vertexPosition_modelspace,1.0);
gl_Position = P * V * M * vec4(vertexPosition_modelspace, 1);
// propagate the position of the vertex to fragment shader
vertex_position_modelspace = vertexPosition_modelspace;
//propagte vertex in world space
vec4 vm=M*vec4(vertexPosition_modelspace, 1);
vertexWorldspace=vm.xyz;
//propagate the normal of the vertex to fragment shader
vertex_normal_modelspace = vertexNormal_modelspace;
// propagate the UV coordinates
vertex_UV = vertexUV;
}
在这里,我将跳过照明计算,因为它们可以正常工作。我在末尾添加了额外的行,以使对象以与立方体图中的深度相对应的颜色显示: 2n渲染循环片段着色器
uniform sampler2D diffuseColorSampler;
uniform sampler2D specularColorSampler;
uniform samplerCube shadowMap;
float ShadowCalculation(vec3 fragPos)
{
vec3 lightPos=light_position_worldspace;
vec3 fragToLight = fragPos - lightPos;
float closestDepth = texture(shadowMap, fragToLight).r;
closestDepth *= 25.0;
float currentDepth = length(fragToLight);
float bias = 0.05;
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
return shadow;
}
//skipping to the end of the main loop
//fragment_color is the output
vec3 fragToLight = vertexWorldspace - light_position_worldspace;
float closestDepth = texture(shadowMap, fragToLight).r;
if(closestDepth>0){
fragment_color = vec4(1.0,0,0, 1.0);
}
fragment_color = vec4(vec3(closestDepth / 25.0), 1.0);
运行此命令,每个对象都是黑色的。我认为这意味着您在右上方看到的变量“ closestDepth”始终为零,这意味着多维数据集映射有问题……