我想要实现一个多光源阴影贴图,在调试之后,glGetError已经不报错了,光照情况是正确的,但是阴影就是没有实现,不明白是什么原因。
下面是我的代码:
……//初始化
Shader shader("D:/cppalbum/shader/lighting/pointDepth/multiDepthVert.glsl",
"D:/cppalbum/shader/lighting/pointDepth/multiDepthFrag.glsl");
Shader simpleDepthShader("D:/cppalbum/shader/lighting/pointDepth/cubeVert.glsl",
"D:/cppalbum/shader/lighting/pointDepth/cubeFrag.glsl",
"D:/cppalbum/shader/lighting/pointDepth/cubeGeo.glsl");
shader.use();
shader.setInt("diffuseMap", 0);
Model mc("D:/cppalbum/texture/T2/test2.obj");
unsigned int wood = loadTexture("D:/cppalbum/texture/Wooden_floor.jpg");
const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
// create depth cubemap texture
unsigned int fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
unsigned int depthCubeMapArray;
glGenTextures(1, &depthCubeMapArray);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
// 为每个立方体贴图分配内存
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT,
SHADOW_WIDTH, SHADOW_HEIGHT, 4 * 6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
const int NUM_LIGHTS = 4;
// 绑定每个立方体贴图到数组中
shader.setInt("depthMap", 1);
glm::vec3 lightPos[4] = {
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 1.0f),
glm::vec3(0.0f, 2.0f, 0.0f),
glm::vec3(1.0f, 1.0f, 1.0f) };
//主循环
// ------------------------------------------------------------------
while (!glfwWindowShouldClose(window))
{
// per-frame time logic
// --------------------
float currentFrame = static_cast<float>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// input
// -----
processInput(window);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float near_plane = 1.0f;
float far_plane = 25.0f;
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane);
for (int i = 0; i < 4; ++i)
{
std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj *
glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0, i * 6);
glClear(GL_DEPTH_BUFFER_BIT);
simpleDepthShader.use();
for (unsigned int j = 0; j < 6; ++j)
simpleDepthShader.setMat4("shadowMatrices[" + std::to_string(j) + "]", shadowTransforms[j]);
simpleDepthShader.setFloat("far_plane", far_plane);
simpleDepthShader.setVec3("lightPos", lightPos[i]);
renderScene(simpleDepthShader, mc, wood);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 激活纹理单元
glActiveTexture(GL_TEXTURE1);
// 绑定立方体贴图数组纹理
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
// 2. render scene as normal
// -------------------------
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = camera.GetViewMatrix();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
// set lighting uniforms
for (unsigned int i = 0; i < 4; ++i)
shader.setVec3("lightPos["+std::to_string(i)+"]", lightPos[i]);
shader.setVec3("viewPos", camera.Position);
shader.setInt("shadows", shadows); // enable/disable shadows by pressing 'SPACE'
shader.setFloat("far_plane", far_plane);
renderScene(shader, mc, wood);
……//剩余部分
着色器(只放fs和几何着色器了,顶点没啥用也不会有问题):
multiDepthFrag.glsl
#version 330 core
out vec4 FragColor;
in VS_OUT {
vec3 FragPos;
vec3 Normal;
vec2 TexCoords;
} fs_in;
uniform sampler2D diffuseTexture;
uniform samplerCubeArray depthMap;
uniform vec3 lightPos[4];
uniform vec3 viewPos;
uniform float far_plane;
uniform bool shadows;
vec3 sampleOffsetDirections[20] = vec3[]
(
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
);
float ShadowCalculation(vec3 fragPos,int i)
{
// Get vector between fragment position and light position
vec3 fragToLight = fragPos - lightPos[i];
float currentDepth = length(fragToLight);
// Now test for shadows
float shadow = 0.0;
float bias = 0.05;
int samples = 20;
float viewDistance = length(viewPos - fragPos);
float diskRadius = (1.0 + (viewDistance / far_plane)) / 25.0;
for (int i=0;i<samples;++i)
{
float closestDepth = texture(depthMap, vec4(fragToLight + sampleOffsetDirections[i] * diskRadius,i)).r;
closestDepth *= far_plane; // Undo mapping [0;1]
if(currentDepth - bias > closestDepth)
shadow += 1.0;
}
shadow /= samples;
return shadow;
}
void main()
{
vec3 color = texture(diffuseTexture, fs_in.TexCoords).rgb;
vec3 normal = normalize(fs_in.Normal);
vec3 lightColor = vec3(0.3);
// Ambient
vec3 ambient = 0.3 * color;
FragColor = vec4(0.0f);
int lightNum=4;
float lightNums = lightNum;
// Diffuse
for (int i=0;i<lightNum;++i)
{
vec3 lightDir = normalize(lightPos[i] - fs_in.FragPos);
float diff = max(dot(lightDir, normal), 0.0);
vec3 diffuse = diff * lightColor;
// Specular
vec3 viewDir = normalize(viewPos - fs_in.FragPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 64.0);
vec3 specular = spec * lightColor;
// Calculate shadow
float shadow = shadows ? ShadowCalculation(fs_in.FragPos, i) : 0.0;
vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular)) * color;
FragColor += vec4(lighting, 1.0f);
}
FragColor /= lightNums;
}
cubeGeo.glsl
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;
uniform mat4 shadowMatrices[6];
out vec4 FragPos; // FragPos from GS (output per emitvertex)
void main()
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face; // built-in variable that specifies to which face we render.
for(int i = 0; i < 3; ++i) // for each triangle's vertices
{
FragPos = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPos;
EmitVertex();
}
EndPrimitive();
}
}
cubeFrag.glsl
#version 330 core
in vec4 FragPos;
uniform vec3 lightPos;
uniform float 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 / far_plane;
// write this as modified depth
gl_FragDepth = lightDistance;
}
现在的显示是这样的:
调试了一中午了