为什么在第二遍中没有渲染深度纹理?

时间:2021-05-22 14:56:56

标签: c++ opengl graphics shadow

我正在开发自己的游戏引擎并在此过程中学习 OpenGL,并且我在阴影贴图上的时间比我想承认的要长。

我一直在遵循本指南:https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping 但我无法在我的飞机上绘制任何阴影。

result

这是代码在我的项目中的样子:

用于创建深度纹理的帧缓冲区:

 glCreateFramebuffers(1, &m_framebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferID);glGenTextures(1, &depthMapID); 

ui32 depthMapID;    
glBindTexture(GL_TEXTURE_2D, depthMapID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMapID, 0);
ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer is incomplete!");
glBindFramebuffer(GL_FRAMEBUFFER, 0);  

深度纹理着色器(忽略未使用的顶点布局):

#type vertex
#version 330 core
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec3 vertex_normal;    
layout (location = 3) in vec3 vertex_tangent;
layout (location = 4) in vec2 vertex_texcoord;

uniform mat4 u_lightViewProjectionMatrix;  
uniform mat4 u_worldTransformMatrix; 

void main()
{
    gl_Position = u_lightViewProjectionMatrix * (u_worldTransformMatrix * vec4(vertex_position, 1.0));
}  

#type fragment
#version 330 core

// Ouput data
//layout(location = 0) out float fragmentdepth;

void main(){
    // Not really needed, OpenGL does it anyway
    //fragmentdepth = gl_FragCoord.z;
}

这就是我创建阴影贴图的方式

if (s_castingShadowMeshes.Size() == 0)
    return;

float shadowDistance = 100.0f;          
glm::mat4 lightView = glm::lookAt(LightManager::GetDirectionalLight().direction * -shadowDistance, glm::vec3(0.0f), MathUtils::Vector3UnitY);
glm::mat4 lightProjection = glm::ortho(-shadowDistance, shadowDistance, -shadowDistance, shadowDistance, 0.0f, shadowDistance * 2.0f);

s_lightViewProjection = lightProjection * lightView;    

glBindFramebuffer(GL_FRAMEBUFFER, m_framebufferID);
glViewport(0, 0, 1024, 1024); //Shadow height and width is 1024

glDepthMask(GL_TRUE);
glClearDepth(1.0f);
glClearColor(color.r, color.g, color.b, color.a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT););

for (ui32 i = 0; i < s_castingShadowMeshes.Size(); ++i)
{
    s_depthMapShader->Bind();
    s_depthMapShader->SetUniform(UNIFORM_LIGHT_SPACE_TRANSFORM, ShaderDataType::Mat4, &(s_lightViewProjection));
    s_depthMapShader->SetUniform(UNIFORM_MODEL_SPACE_TRANSFORM, ShaderDataType::Mat4, &(s_castingShadowMeshes[i]->GetWorldTransform()[0][0]));
    s_rendererPlatformInterface->DrawVertexArray(s_castingShadowMeshes[i]->GetVertexArray());

    s_renderStats.drawCalls++;
    s_depthMapShader->Unbind();
}
s_shadowFramebuffer->Unbind();      

到目前为止,RenderDoc 向我展示了实际上正在生成深度纹理:

renderdoc depth texture

现在,这就是渲染飞机的样子:

shader->Bind();

ui32 useShadowMapTex = 0;           
if (receiveShadows)
{
    useShadowMapTex = 1;
    ui32 shadowMapSlot = (ui32)Material::TextureSlots::ShadowMap;
    shader->SetUniform(UNIFORM_SHADOWMAP_TEX, ShaderDataType::Int, &shadowMapSlot);
    s_shadowMapTex->Bind(shadowMapSlot);
}

shader->SetUniform(UNIFORM_USE_SHADOWMAP_TEX, ShaderDataType::Int, &useShadowMapTex);
shader->SetUniform(UNIFORM_MODEL_SPACE_TRANSFORM, ShaderDataType::Mat4, &(transform[0][0]));
shader->SetUniform(UNIFORM_VIEW_PROJECTION, ShaderDataType::Mat4, &(s_sceneData.viewProjectionMatrix));
shader->SetUniform(UNIFORM_CAMERA_POS, ShaderDataType::Float3, &(s_sceneData.cameraPosition));

shader->SetUniform(UNIFORM_DIR_LIGHT_DIRECTION, ShaderDataType::Float3, &(LightManager::GetDirectionalLight().direction));
shader->SetUniform(UNIFORM_DIR_LIGHT_AMBIENT,ShaderDataType::Float3, &(LightManager::GetDirectionalLight().ambientColor));
shader->SetUniform(UNIFORM_DIR_LIGHT_DIFUSSE, ShaderDataType::Float3, &(LightManager::GetDirectionalLight().diffuseColor));
shader->SetUniform(UNIFORM_DIR_LIGHT_SPECULAR, ShaderDataType::Float3, &(LightManager::GetDirectionalLight().specularColor));

s_rendererPlatformInterface->DrawVertexArray(vertexArray);

s_renderStats.drawCalls++;
s_renderStats.vertices += vertexArray->GetIndexBuffer()->GetCount();

平面着色器:

#type vertex
#version 330 core

layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec3 vertex_normal;    
layout (location = 3) in vec3 vertex_tangent;
layout (location = 4) in vec2 vertex_texcoord;

out VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
    vec4 FragPosLightSpace; 
} vs_out;

uniform mat4 u_viewProjectionMatrix;  
uniform mat4 u_worldTransformMatrix;
uniform mat4 u_lightViewProjectionMatrix;

void main()
{    
    vs_out.FragPos = vec3(u_worldTransformMatrix * vec4(vertex_position, 1.0));
    vs_out.Normal = transpose(inverse(mat3(u_worldTransformMatrix))) * vertex_normal;
    vs_out.TexCoords = vertex_texcoord; 
    vs_out.FragPosLightSpace = u_lightViewProjectionMatrix * vec4(vs_out.FragPos, 1.0);
    gl_Position = u_viewProjectionMatrix* vec4(vs_out.FragPos, 1.0);
}

#type fragment
#version 330 core
out vec4 FragColor;

in VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
    vec4 FragPosLightSpace;
} fs_in;

struct DirectionalLight 
{
    vec3 direction;  

    vec3 ambientColor;
    vec3 diffuseColor;
    vec3 specularColor;
};

uniform DirectionalLight u_directionalLight;
uniform sampler2D u_shadowMapTex;
uniform vec3 u_cameraPos;

float ShadowCalculation(vec4 fragPosLightSpace)
{
    // perform perspective divide
    vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
    // transform to [0,1] range
    projCoords = projCoords * 0.5 + 0.5;
    // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
    float closestDepth = texture(u_shadowMapTex, projCoords.xy).r; 
    // get depth of current fragment from light's perspective
    float currentDepth = projCoords.z;
    // check whether current frag pos is in shadow
    float shadow = currentDepth > closestDepth  ? 1.0 : 0.0;

    return shadow;
}

void main()
{           
    vec3 normal = normalize(fs_in.Normal);
    vec3 lightColor = vec3(1.0);
    // ambient
    vec3 ambient = u_directionalLight.ambientColor;
    // diffuse
    vec3 lightDir = normalize(u_directionalLight.direction);
    float diff = max(dot(lightDir, normal), 0.0);
    vec3 diffuse = diff * lightColor;
    // specular
    vec3 viewDir = normalize(u_cameraPos - fs_in.FragPos);
    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 = ShadowCalculation(fs_in.FragPosLightSpace);       
    vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular));    

    FragColor = vec4(lighting, 1.0);
}

这是我得到的:

result

根据RenderDoc,阴影贴图纹理实际上是在着色器中传递的,但它从未在红色平面中绘制: renderdoc result

我希望有人能帮助我。非常感谢。

p.d:这是我在 StackOverflow 上的第一篇文章,如果我违反了任何规则,请见谅。

0 个答案:

没有答案
相关问题