带有 FBO 的 OpenGL 阴影映射 - 多个拖尾绘制

Posted

技术标签:

【中文标题】带有 FBO 的 OpenGL 阴影映射 - 多个拖尾绘制【英文标题】:OpenGL Shadow Mapping with FBO - multiple trailing draw 【发布时间】:2013-01-31 10:14:32 【问题描述】:

我正在尝试在我们的游戏项目中实现阴影映射。我正在使用渲染到纹理技术和两遍渲染。我首先创建了一个 FBO,并仅为深度组件绑定了一个纹理。在第一遍中,我启用了这个 FBO,禁用纹理并从光 POV 渲染我的场景。在第二遍中,我将深度纹理传递给着色器并正常渲染场景。我在着色器中执行与阴影相关的计算。

但是,我的代码不能正常工作。我看不到任何阴影。此外,当我渲染两个通道时,如果我的相机在某个角度上方看时,我会看到整个世界的多个绘图一个接一个地尾随:45。如果我看低于该角度,渲染看起来还不错。这个问题的根源可能是什么? .如果我禁用第一遍,世界看起来更暗,但尾随场景消失了。我还在下面附上了我的代码。

我还有另一个困惑。我为第一个阴影贴图通道禁用了纹理。但是我将纹理坐标与我的顶点坐标一起发送到 VBO。会不会有什么问题?

FBO 初始化

LightPosition = glm::vec3(50.0f, 40.0f, 50.0f);  
upVector = glm::vec3(0.0f, 1.0f, 0.0f);  

glGenTextures(1, &m_shadowMap);  
glBindTexture(GL_TEXTURE_2D, m_shadowMap);  
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_CLAMP);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);  
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);  
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,  
        WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);  
glBindTexture(GL_TEXTURE_2D, 0);  

glGenFramebuffers(1, &m_fbo);  
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);  
glDrawBuffers(0, NULL);  
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);  
glBindFramebuffer(GL_FRAMEBUFFER, 0);  

glEnable(GL_DEPTH_TEST);  
glEnable(GL_CULL_FACE);  


GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);  

if (Status != GL_FRAMEBUFFER_COMPLETE)   
    printf("FB error, status: 0x%x\n", Status);  
    return false;  
  

return true;  

阴影贴图通行证:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);


glViewport(0, 0, windowWidth, windowHeight);

glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO.m_fbo);

glClear(GL_DEPTH_BUFFER_BIT);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 lightProjection = glm::perspective(45.0f,
        1.0f * windowWidth / windowHeight, 0.125f, 1000.0f);
glGetFloatv(GL_PROJECTION_MATRIX, shadowMapFBO.LightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 lightModelView = glm::lookAt(shadowMapFBO.LightPosition,
        glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glGetFloatv(GL_MODELVIEW_MATRIX, shadowMapFBO.LightModelViewMatrix);

glm::mat4 lmvp = lightProjection * lightModelView;

glCullFace(GL_FRONT);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);

glUniform1i(Shader::id_uniform_layer, 0);
world->render(lmvp);
printGLError();


glBindFramebuffer(GL_FRAMEBUFFER, 0);

渲染通道:

static glm::vec3 cCameraPosition = glm::vec3(0.0f, 5.0f, 10.0f);
static glm::vec3 cLightPosition = glm::vec3(50.0f, 40.0f, 50.0f);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, windowWidth, windowHeight);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 modelView = player->getView();

float viewAngle = 45.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 projection = glm::perspective(viewAngle,
        1.0f * windowWidth / windowHeight, 0.01f, 1000.0f);
glm::mat4 mvp = projection * modelView;


glEnable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowMapFBO.m_shadowMap);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.5f);
glScalef(0.5f, 0.5f, 0.5f);
glMultMatrixf(shadowMapFBO.LightProjectionMatrix);
glMultMatrixf(shadowMapFBO.LightModelViewMatrix);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_texture_blocks);

glUseProgram(Shader::id_program);

glUniform3fv(Shader::id_uniform_lightPosition, 1,
        glm::value_ptr(cLightPosition));
glUniform3fv(Shader::id_uniform_CameraPosition, 1,
        glm::value_ptr(*(player->getCoordinates())));

//Enabling color write (previously disabled for light POV z-buffer rendering)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glUniform1i(Shader::id_shader_shadow, 1);

glUniformMatrix4fv(Shader::id_uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));

glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_CULL_FACE);

glCullFace(GL_BACK);

glUniform1i(Shader::id_uniform_layer, 0);
world->render(mvp);
printGLError();

顶点着色器:

attribute vec4 coordinates;
uniform   mat4 mvp;

//Fragment shader forward variables.
varying vec4 voxel;

//shadow map
// Used for shadow lookup
varying vec4 ShadowCoord;

uniform vec3 LightPosition, CameraPosition;

varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;

void main(void) 

//shadow map
LightDirection = LightPosition - gl_Vertex.xyz;
LightDirectionReflected = reflect(-LightDirection, gl_Normal);
CameraDirection = CameraPosition - gl_Vertex.xyz;
Normal = gl_Normal;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_Vertex;

voxel = coordinates;
//Calculates projection on xyz.
gl_Position = mvp * vec4(coordinates.xyz, 1);

片段着色器:

#extension GL_EXT_gpu_shader4 : enable  


//Rendering layer.  
uniform int layer;  


//Colors.  
uniform float colorRed;  
uniform float colorGreen;  
uniform float colorBlue;  
uniform float colorAlpha;  

//Fog density.  
uniform float fogDensity;  

varying vec4 voxel;  

uniform sampler2D texture;  

const float N_TEXTURES = 32.0;  

//////////////////////shadow map  
uniform sampler2DShadow ShadowMap;  

varying vec4 ShadowCoord;  

varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;  

void main(void)   

vec2  coord2d;  
float intensity;  

vec4 color = texture2D(texture, coord2d);  

float z = gl_FragCoord.z / gl_FragCoord.w;  
float fog = clamp(exp(-fogDensity * z * z), 0.2, 1.0);  

color.xyz = color.xyz * intensity;  

//shadow map  
float Shadow = shadow2DProj(ShadowMap, gl_TexCoord[1]).r;  

float NdotLD = max(dot(normalize(LightDirection), Normal), 0.0) * Shadow;  
float Spec = pow(max(dot(normalize(LightDirectionReflected), normalize(CameraDirection)), 0.0), 32.0) * Shadow;  
color.xyz = color.xyz * (0.25 + NdotLD * 0.75 + Spec);  

//Final color.  
vec4 fogColor = vec4(colorRed, colorGreen, colorBlue, colorAlpha);  
gl_FragColor = mix(fogColor, color, fog);  


  

【问题讨论】:

你的#version指令在哪里? 版本已在着色器生成代码中定义。它的值为 1.20(通过语句 - #version 120\n)。 【参考方案1】:

乍一看,您似乎没有使用glClear,所以天空是最后一帧中的任何内容,或者至少它不起作用。 glClearColor 的 alpha 值是多少?

【讨论】:

以上是关于带有 FBO 的 OpenGL 阴影映射 - 多个拖尾绘制的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL阴影映射,具有多个glDrawElements的帧缓冲区

阴影贴图上的高斯模糊(FBO/纹理)

OpenGL 渲染到 FBO

如何在 OpenGL 中使用立方体贴图数组来渲染带有阴影贴图的多个点光源?

使用带有延迟渲染 Opengl 3.3 的阴影贴图的问题

使用带有 FBO 的 OpenGL 3.2+ 的 Linux 屏幕外渲染