我正在尝试在我的项目中使用阴影贴图。我按照Learn OpenGL Tutorial上的教程进行了操作。出于某种原因,我无法看到阴影,只能看到片段着色器中照明代码的镜面反射。 Image from render
以下是我如何进行帧缓冲设置(frameBuffer
和DepthMap
是两个全局GLuint
):
void createFrameBuffer()
{
glGenFramebuffers(1, &frameBuffer);
glGenTextures(1, &DepthMap);
glBindTexture(GL_TEXTURE_2D, DepthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
然后我继续设置几何
glGenVertexArrays(1, &shadowVertexAttribute);
glBindVertexArray(shadowVertexAttribute);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
//Texture Map
glUniform1i(glGetUniformLocation(sShaderProgram, "DepthMap"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, DepthMap);
//Normal Map
glUniform1i(glGetUniformLocation(sShaderProgram, "DiffuseMap"), 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureMap);
glUniform3fv(glGetUniformLocation(sShaderProgram, "lightPos"), 1, glm::value_ptr(lightPos));
GLuint shadowVertBuffer;
GLuint shadowUVBuffer;
GLuint shadowNormalBuffer;
for (int i = 0; i < objmesh.size(); i++) {
glGenBuffers(1, &shadowVertBuffer);
glBindBuffer(GL_ARRAY_BUFFER, shadowVertBuffer);
glBufferData(GL_ARRAY_BUFFER, objmesh[i]->vertices.size() * sizeof(glm::vec3), &objmesh[i]->vertices[0], GL_STATIC_DRAW);
GLuint svertexPos = glGetAttribLocation(sShaderProgram, "vertex_position");
glVertexAttribPointer(svertexPos, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glGenBuffers(1, &shadowUVBuffer);
glBindBuffer(GL_ARRAY_BUFFER, shadowUVBuffer);
glBufferData(GL_ARRAY_BUFFER, objmesh[i]->uvs.size() * sizeof(glm::vec2), &objmesh[i]->uvs[0], GL_STATIC_DRAW);
GLuint svertexUV = glGetAttribLocation(sShaderProgram, "vertex_UV");
glVertexAttribPointer(svertexUV, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glGenBuffers(1, &shadowNormalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, shadowNormalBuffer);
glBufferData(GL_ARRAY_BUFFER, objmesh[i]->normals.size() * sizeof(glm::vec3), &objmesh[i]->normals[0], GL_STATIC_DRAW);
GLuint svertexNormal = glGetAttribLocation(sShaderProgram, "vertex_normal");
glVertexAttribPointer(svertexNormal, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
}
最后,我渲染阴影(或至少尝试):
if (shadows == true) {
glUseProgram(sShaderProgram);
glBindVertexArray(shadowVertexAttribute);
glm::mat4 lightProjection = glm::ortho(-3000.0f, 3000.0f, -3000.0f,
3000.0f, NEARPLANE, FARPLANE);
glm::mat4 lightView = glm::lookAt(lightPos, glm::vec3(0.0),
glm::vec3(0.0, 1.0, 0.0));
glm::mat4 lightSpaceMatrix = lightProjection * lightView;
glUniformMatrix4fv(glGetUniformLocation(sShaderProgram, "lightSpaceMatrix"),
1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
glUniformMatrix4fv(glGetUniformLocation(sShaderProgram, "modelMatrix"),
1, GL_FALSE, glm::value_ptr(mesh.modelMatrix));
//rendering to depthmap
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glClear(GL_DEPTH_BUFFER_BIT);
GLuint texLocation = glGetUniformLocation(sShaderProgram, "DepthMap");
glUniform1i(texLocation, 0);
texLocation = glGetUniformLocation(sShaderProgram, "DiffuseMap");
glUniform1i(texLocation, 1);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, DepthMap);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textureMap);
glDrawArrays(GL_TRIANGLES, 0, mesh.vertices.size());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
setViewPort();
}
如果需要,这里还有Shadow Vertex和Shadow Fragment着色器。
顶点:
//Vertex Shader
#version 440
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec2 vertex_UV;
layout(location = 2) in vec3 vertex_normal;
uniform mat4 modelMatrix;
uniform mat4 lightSpaceMatrix;
out vec3 outVertex;
out vec2 outTexCoords;
out vec3 outNormals;
out vec4 outVertexLightSpace;
layout(binding = 3 , std140) uniform uniformBlock
{
vec3 camPos;
mat4 world;
mat4 LookAt;
mat4 projection;
mat4 MVP;
};
layout(binding = 4 , std140) uniform materials
{
vec3 Diffuse;
vec3 Ambient;
vec3 Translucency;
//char texturePath[128];
float refraction;
vec3 Specular;
float PhongSpecular;
};
void main()
{
outVertex = vec3(modelMatrix * vec4(vertex_position, 1.0));
outTexCoords = vertex_UV;
outNormals = transpose(inverse(mat3(modelMatrix))) * vertex_normal;
outVertexLightSpace = lightSpaceMatrix * vec4(vertex_position, 1.0f);
gl_Position = projection * LookAt * modelMatrix * vec4(vertex_position ,
1.0);
}
片段:
//Fragment Shader
#version 440
out vec4 fragment_color;
uniform sampler2D DepthMap;
uniform sampler2D DiffuseMap;
uniform vec3 lightPos;
in vec3 outVertex;
in vec2 outTexCoords;
in vec3 outNormals;
in vec4 outVertexLightSpace;
layout(binding = 3 , std140) uniform uniformBlock
{
vec3 camPos;
mat4 world;
mat4 LookAt;
mat4 projection;
mat4 MVP;
};
float CalculateShadow(vec4 fragPos){
vec3 projCoords = outVertexLightSpace.xyz / outVertexLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float closestDepth = texture(DepthMap, projCoords.xy).r;
float currentDepth = projCoords.z;
float shadow;
if(currentDepth > closestDepth) {
shadow = 1.0;
}
else {
shadow = 0.0;
}
return shadow;
}
void main()
{
vec3 color = texture(DiffuseMap, outTexCoords).rgb;
vec3 normal = normalize(outNormals);
vec3 lightColor = vec3(1.0);
vec3 ambient = 0.4 * color;
vec3 lightDir = normalize(lightPos - outVertex);
float diff = max(dot(lightDir, normal), 0.0);
vec3 diffuse = diff * lightColor;
vec3 viewDir = normalize(camPos - outVertex);
vec3 halfWayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(normal, halfWayDir), 0.0), 64.0);
vec3 specular = spec * lightColor;
float shadowValue = CalculateShadow(outVertexLightSpace);
vec3 lighting = (ambient + (1.0 - shadowValue) * (diffuse + specular)) * color;
fragment_color = vec4(lighting, 1.0);
}
如果您有任何可能出错的指示,我会很高兴听到它们。感谢您提前得到的所有帮助:D