我对阴影贴图感到困惑。这是我的理解(以下步骤不起作用:))
如何获取 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)
一般情况:
- 创建一个深度纹理
- 将此纹理附加到 FBO
- 绑定(bind)FBO,设置正确的视口(viewport)
- 从灯光位置渲染场景,仅将深度值保存到纹理
- 解除绑定(bind) FBO 并设置最终场景视口(viewport)和摄像机位置
- 通常使用阴影测试 (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/