opengl - 阴影贴图混淆

标签 opengl shadow-mapping

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

如何获取 yield (请不要对代码感到困惑,大概是因为我是用Java写的):

1.使用参数创建空的深度纹理(我的是​​1024x1024)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 宽度, 高度, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_NULL)

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

glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,深度纹理,0)

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

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

4. 创建新的小着色器来确定 FBO 的 gl_Position 并使用奇特的东西修改主着色器(偏差矩阵 * lightCamera 矩阵 * 顶点、sampler2Dshadow 等)

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

现在渲染循环

1.当然统一一切并(再次)做一些事情。

2. 绑定(bind) FBO,绑定(bind)小着色器,glViewport(0, 0, 1024, 1024),colorMask 为 false,清除深度缓冲区,glCullFace( GL_FRONT), glBindTexture(GL_TEXTURE_2D, 0)

3.仅使用顶点位置属性渲染所有内容完全没有任何作用

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

5. 正常渲染场景,甚至不用考虑“主着色器到底如何获得 sampler2DShadow,因为我们不绑定(bind)它,不统一它,也不考虑它”甚至触摸它”

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

实际上,我尝试将深度纹理统一到采样器,但我只有黑屏。即使我不渲染 FBO,我也会得到相同的图片。

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

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

最佳答案

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

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

一般情况:

  1. 创建一个深度纹理
  2. 将此纹理附加到 FBO
  3. 绑定(bind)FBO,设置正确的视口(viewport)
  4. 从灯光位置渲染场景,仅将深度值保存到纹理
  5. 解除绑定(bind) FBO 并设置最终场景视口(viewport)和摄像机位置
  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();

关于opengl - 阴影贴图混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14241348/

相关文章:

opengl - GL_ALPHA8 已从 OpenGL 3.1 中删除,有哪些替代方案?

opengl - 使用立方体贴图(OpenGL/GLSL)的点光是否可以实现软阴影?

OpenGL 3.3 两个 GPU 上具有阴影贴图的 nVidia Optimus 上的两种不同结果

c++ - 如何在透视 View 中绘制文本

c++ - 设置GL_TEXTURE_2D_ARRAY,帧缓冲区不完整

java/opengl : loading textures on 64bit VM

c++ - 使用立方体贴图在 Opengl-es 2.0 中进行阴影映射

c++ - 使用阴影贴图将 OpenGL 场景渲染为黑色

c++ - 场景/视口(viewport)之外的对象 (OpenGL)