2

我对阴影贴图感到困惑。这是我所理解的(以下步骤不起作用:))

如何获得利润(请不要对代码感到困惑,大致是因为我是用Java写的):

1.用参数创建空的depthTexture(我的是1024x1024)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_NULL)

2.创建 FBO 并将该纹理附加到它

glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0)

3.为照明相机设置新的投影和视图矩阵

我使用与我的主相机相同的另一个坐标,因为场景看起来更好(我试过了,所以没有问题......我猜..)。

4.创建新的小着色器来确定 FBO 的 gl_Position 并用花哨的东西修改主着色器(偏置矩阵 * lightCamera 矩阵 * 顶点,sampler2Dshadow 等等)

5.当然要统一一切,做一些事情。

现在渲染循环

1.当然要统一一切并做某事(再次)。

2.绑定FBO,绑定little shader,,glViewport(0, 0, 1024, 1024)colorMask为false,清除深度缓冲区glCullFace(GL_FRONT),,glBindTexture(GL_TEXTURE_2D, 0)

3.只使用顶点位置属性完全渲染一切

4.取消绑定FBO,将程序重新绑定到主着色器(那个有花哨的东西)glViewport,启用colorMask,glCullFace(GL_BACK)

5.正常渲染场景,甚至不用考虑“该死的主着色器将如何得到sampler2DShadow,因为我们不绑定它,不统一它,甚至不触摸它”

6.观看无数的故障、错误和像素狂欢

实际上我试图将 depthTexture 统一到采样器,但我只有黑屏。即使我不渲染 FBO,当我这样做时,我也会得到相同的画面。

有人可以解释一下,我错过了什么吗?

我觉得着色器使用了漫反射纹理两次:作为漫反射纹理和作为depthTexture,但我不知道如何给它那个depthTexture。

4

1 回答 1

4

这是一个很好的阅读链接:http ://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/

在这里: http: //www.paulsprojects.net/tutorials/smt/smt.html(虽然第二个链接使用旧的固定功能opengl)

一般来说:

  1. 创建一个深度纹理
  2. 将此纹理附加到 FBO
  3. 绑定FBO,设置正确的视口
  4. 从灯光位置渲染场景,仅将深度值保存到纹理
  5. 取消绑定 FBO 并设置最终场景视口和摄像机位置
  6. 使用阴影测试(sampler2DShadow)正常渲染场景

您可以始终(在渲染循环中)或仅在光照位置发生变化时渲染深度图。

我不知道你为什么要正常渲染你的场景两次……你是在使用 Z-prepass 还是什么?试试我认为的基本版本。

我的带有阴影贴图的旧代码:

void RenderShadowMap() {
    currDepth->Bind();
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gLightCam.SetProjectionMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gLightCam.SetViewMatrix();

    glColorMask(false, false, false, false);
    glUseProgram(0);   // draw without any shaders... just default depth
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(offFactor, offUnits);
    SimpleScene(false); // floor does not cast shadow so do not render it
    glDisable(GL_POLYGON_OFFSET_FILL);
    glColorMask(true, true, true, true);
}

渲染场景:

// compose shadow matrix:
MATRIX4X4 bias(0.5f, 0.0f, 0.0f, 0.0f, 
               0.0f, 0.5f, 0.0f, 0.0f,
               0.0f, 0.0f, 0.5f, 0.0f,
               0.5f, 0.5f, 0.5f, 1.0f);
MATRIX4X4 *invCam = gSphericalCam.GetInvViewMatrix();
MATRIX4X4 smMat = (*gLightCam.GetViewProjMatrix()) * (*invCam);

gShaderProgramManager->GetProgram("shadow")->Use();
gShaderProgramManager->GetProgram("shadow")->SetMatrix("shadowMat", &smMat);
gShaderProgramManager->GetProgram("shadow")->SetBool("useShadow", currCam != &gLightCam && useShadow);
gShaderProgramManager->GetProgram("shadow")->SetFloat("shadowMapSize", (float)currDepth->GetWidth());
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 1.0f);
gTextureManager->Bind("default");
glActiveTexture(GL_TEXTURE1);
currDepth->BindDepthAsTexture();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

SimpleScene();
于 2013-01-09T17:44:00.400 回答