我使用矢量作为光位置说(0.0f,0.0f,5.0f)和一个位于(0.0f,0.0f,-10.0f)的物体和一个平面。
lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 300.0f);
lightSpaceView= glm::lookAt(lightPosition, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
lightSpaceMatrix = lightSpaceProjection * lightSpaceView;
随着相机随处可见阴影,我想知道如何更新阴影贴图以渲染相机所在的正确空间阴影。
我计算了如图所示的光照空间矩阵,将其发送到顶点着色器,从光源视图渲染阴影贴图,然后再将其发送到普通顶点着色器,以计算哪个片段处于阴影中,
灯光定义
DirectLight sun;
sun.direction = glm::vec3(0.0f, 10.0f, 5.0f);
sun.lightSpaceProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 300.0f);
sun.lightSpaceView= glm::lookAt(sun.direction, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
scene.addLight("sun", sun);
这是渲染代码
DirectLight& sun = dynamic_cast<DirectLight&>(this->getLight("sun", LIGHTTYPE_DIRECT));
glm::mat4 lightSpaceMatrix = (sun.lightSpaceProjection * sun.lightSpaceView);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
//glCullFace(GL_FRONT);
typedef std::map<std::string, Model>::iterator model_it;
depthShader.use();
glUniformMatrix4fv(glGetUniformLocation(depthShader.getProgramID(), "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
for (model_it it = phongModels.begin(); it != phongModels.end(); it++) {
((Model&) it->second).drawDepth(depthShader);
}
//glCullFace(GL_BACK);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// draw normal
glViewport(0, 0, WIDTH, HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
typedef std::map<std::string, Model>::iterator model_it;
phongShader.use();
glUniformMatrix4fv(glGetUniformLocation(phongShader.getProgramID(), "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
this->drawPhongLights(phongShader);
this->setViewUniforms(phongShader);
for (model_it it = phongModels.begin(); it != phongModels.end(); it++) {
glActiveTexture(GL_TEXTURE2);
glUniform1i(glGetUniformLocation(phongShader.getProgramID(), "shadowMap"), 2);
glBindTexture(GL_TEXTURE_2D, depthMap);
((Model&) it->second).drawPhong(phongShader, this->defCamera);
}
深度顶点着色器是
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 lightSpaceMatrix;
uniform mat4 model;
void main(){
gl_Position = lightSpaceMatrix * model * vec4(position, 1.0f);
}
,正常的顶点着色器是
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 2) in vec2 texCoord;
layout (location = 1) in vec3 normal;
out vec2 TexCoords;
out vec3 Normal;
out vec3 FragPos;
out vec3 LightPos;
out vec4 FragPosLightSpace;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightPos;
uniform mat4 lightSpaceMatrix;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = vec2(texCoord.s,1.0-texCoord.t);
Normal=normal;
FragPos = vec3(view * model * vec4(position, 1.0f));
LightPos = vec3(view * vec4(lightPos, 1.0));
FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);
}
并在片段着色器中我通过此函数计算阴影
float directShadowCalculation(vec4 fragPosLightSpace,float bias){
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float closestDepth = vec3(texture(shadowMap, projCoords.xy)).r;
float currentDepth = projCoords.z;
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
for(int x = -1; x <= 1; ++x){
for(int y = -1; y <= 1; ++y){
float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
}
}
shadow /= 9.0;
if(projCoords.z > 1.0)
shadow = 0.0;
return shadow;
}
然后应用这个颜色
vec3 calcDirectLight(DirectLight light){
vec3 color = vec3(texture(mat_diffuse, TexCoords));
vec3 norm = normalize(Normal);
vec3 lightDir = normalize( light.direction - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light.diffuse * diff ;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec =0.0;
if(blinn){
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(norm, halfwayDir), 0.0), 16.0);
}
else{
vec3 reflectDir = reflect(-lightDir, norm);
spec = pow(max(dot(viewDir, reflectDir), 0.0), 8.0);
}
//float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
vec3 specular = spec * light.specular;
float bias = max(0.05 * (1.0 - dot(norm, lightDir)), 0.005);
float shadow = directShadowCalculation(FragPosLightSpace,bias);
vec3 result =light.intensity* (light.ambient+ ((1.0 - shadow) * (diffuse + specular)))*color;
return result;
}
我不知道如何使用相机视图更新光线空间平截头体
解决方案: 错误是在顶点着色器中,这是正确的:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 2) in vec2 texCoord;
layout (location = 1) in vec3 normal;
out vec2 TexCoords;
out vec3 Normal;
out vec3 FragPos;
out vec4 FragPosLightSpace;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightPos;
uniform mat4 lightSpaceMatrix;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = vec2(texCoord.s,1.0-texCoord.t);
Normal=transpose(inverse(mat3(model))) * normal;;
FragPos = vec3( model * vec4(position, 1.0f));
FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);
}