在我的阴影贴图实现方向灯我有一个项目集合,我迭代它们将其深度渲染到深度缓冲区然后再次迭代它们以使用生成的阴影贴图正常渲染它们,每个项目都有{{1我测试的属性名为bool
,如果将其添加到深度缓冲区,则问题是如果项目投射阴影并渲染到深度缓冲区,它根本无法接收阴影,一旦我将其设置为false然后它没有呈现为深度,它开始接收阴影而没有问题。
所以在渲染函数中我首先渲染深度缓冲区如下:
castShadow
,渲染功能是:
void Engine::renderDepthMaps() {
if (sun != nullptr) {
if (sun->castShadow) {
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
glm::vec3 pos = -500.0f * sun->direction;
glm::mat4 lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 1000.0f);
glm::mat4 lightSpaceView = glm::lookAt(pos, player->getPosition(), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightSpaceProjection * lightSpaceView;
Shader& shader = shaders.getShader(DEPTH);
shader.use();
shaders.setDepthLightSpaceUniform(shader, lightSpaceMatrix);
for (item_it it = engineItems.begin(); it != engineItems.end(); ++it) {
if (it->get()->castShadow)
it->get()->renderDepth(deltaFirst);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
}
并且着色器是: 顶点:
void Engine::renderMeshes() {
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Shader& basicShader = shaders.getShader(BASIC);
basicShader.use();
sun->setUniforms(basicShader.getProgramID(), "directLights");
shaders.setLightSpaceUniform(basicShader, sun, lightSpaceMatrix, depthMap);
shaders.setShaderViewUniforms(basicShader, camera);
terrain->render(basicShader, deltaFirst);
for (item_it it = basicItems.begin(); it != basicItems.end(); ++it) {
if (it->get()->type != "terrain")
it->get()->render(basicShader, deltaFirst);
}
}
片段:
#version 300 es
precision highp float;
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 lightSpaceMatrix;
uniform mat3 normalMatrix;
out vec4 FragPosLightSpace;
out vec2 TexCoords;
out vec3 Normal;
out vec3 viewPos;
out vec3 fragPos;
void main(){
TexCoords = texCoord;
Normal=normalMatrix*normal;
fragPos = vec3(model * vec4(position,1.0f));
FragPosLightSpace =lightSpaceMatrix * model * vec4(position,1.0f);
gl_Position = projection * view * model * vec4(position,1.0f);
}
另一个问题:光照空间透视矩阵为 #version 300 es
precision highp float;
out vec4 glFragColor;
vec2 poissonDisk[4] = vec2[](
vec2( -0.94201624, -0.39906216 ),
vec2( 0.94558609, -0.76890725 ),
vec2( -0.094184101, -0.92938870 ),
vec2( 0.34495938, 0.29387760 )
);
struct DirectLight {
vec3 direction;
vec3 color;
float intensity;
};
in vec3 Normal;
in vec2 TexCoords;
in vec3 fragPos;
in vec4 FragPosLightSpace;
uniform int has_texture;
uniform vec3 matDiffuse;
uniform sampler2D shadowMap;
uniform sampler2D mat_diffuse;
uniform sampler2D mat_specular;
uniform vec3 matSpecular;
uniform float shininess;
uniform DirectLight sun;
uniform int castShadow;
uniform vec3 viewPos;
void main(){
vec3 tex=vec3(1),spe=vec3(1);
if(has_texture==1){
tex=vec3(texture(mat_diffuse, TexCoords));
spe=vec3(texture(mat_specular,TexCoords));
}
vec3 diffColor = matDiffuse * tex;
vec3 specColor = matSpecular * spe;
vec3 ambient = vec3(0.4,0.4,0.4)*diffColor;
vec3 lightDir = normalize(-sun.direction);
float diff = max(dot(Normal,lightDir), 0.0);
vec3 diffuse = sun.color * diff * diffColor;
vec3 viewDir = normalize(viewPos - fragPos);
vec3 reflectDir = reflect(-lightDir, Normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
vec3 specular = spec * specColor * sun.color;
vec3 color = ambient + diffuse + specular;
float gamma = 2.2;
color.rgb = pow(color.rgb, vec3(1.0/gamma));
if(castShadow==1){
vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float shadow = 1.0;
for (int i=0;i<4;i++){
shadow -= 0.2*(1.0-texture( shadowMap, projCoords.xy + poissonDisk[i]/700.0).r);
}
if(projCoords.z > 1.0)
shadow = 0.0;
color *=shadow;
}
glFragColor=vec4(color,1.0f);
}
,阴影贴图大小为1024,当一个物体位于该矩阵之外时,它会产生非常长的阴影并且方向不正确,如下图所示: