Opengl 阴影贴图混淆
我对阴影贴图感到困惑。以下是我的理解(以下步骤不起作用:) 如何获得利润(请不要对代码感到困惑,这大致是因为我是用Java编写的): 1。使用参数创建空的depthTexture(我的是1024x1024)Opengl 阴影贴图混淆,opengl,shadow-mapping,Opengl,Shadow Mapping,我对阴影贴图感到困惑。以下是我的理解(以下步骤不起作用:) 如何获得利润(请不要对代码感到困惑,这大致是因为我是用Java编写的): 1。使用参数创建空的depthTexture(我的是1024x1024) glTexParameteri(GL\u纹理\u 2D、GL\u纹理\u比较\u模式、GL\u比较\u R\u到\u纹理)和 glTexImage2D(GL\u纹理\u 2D,0,GL\u深度\u分量,宽度,高度,0,GL\u深度\u分量,GL\u浮动,GL\u空) 2.创建FBO并将该纹理
glTexParameteri(GL\u纹理\u 2D、GL\u纹理\u比较\u模式、GL\u比较\u R\u到\u纹理)
和
glTexImage2D(GL\u纹理\u 2D,0,GL\u深度\u分量,宽度,高度,0,GL\u深度\u分量,GL\u浮动,GL\u空)
2.创建FBO并将该纹理附加到FBO上
glFramebufferTexture(GL\u FRAMEBUFFER,GL\u DEPTH\u附件,depthTexture,0)
3.为照明摄像机设置新的投影和视图矩阵
我用了和我的主相机一样的东西,只是用了另一个坐标,因为里面的场景看起来更好(我试过了,所以没问题……我想……)
4.创建新的小着色器,以确定FBO的gl_位置,并使用奇特的东西修改主着色器(偏置矩阵*光照摄影机矩阵*顶点、采样器2D阴影等)
5.当然,要统一一切,做点什么
现在渲染循环
1.当然,统一一切,并(再次)采取行动
2.绑定FBO,绑定小着色器,glViewport(0,0,1024,1024)
,将颜色掩码设置为假,清除深度缓冲区,glCullFace(GL\u-FRONT)
,glBindTexture(GL\u-TEXTURE\u-2D,0)
3.仅使用顶点位置属性完全免费渲染所有内容
4.解除FBO绑定,将程序重新绑定到主着色器(具有奇特功能的着色器),glViewport
,启用颜色掩码,glCullFace(GL_BACK)
5.正常渲染场景,甚至不考虑“该死的主着色器将如何获得sampler2DShadow
,因为我们不绑定它,不统一它,甚至不触摸它”
6.观看无数的小故障、bug和像素狂欢
事实上,我试图将深度纹理统一到采样器,但我只有黑屏。即使我不渲染FBO,当我这样做时,我也会得到相同的图片
谁能解释一下,我错过了什么
我觉得着色器使用漫反射纹理两次:作为漫反射纹理和深度纹理,但我不知道如何赋予它深度纹理。这里有一个很好的链接: 这里:(尽管第二个链接使用旧的固定函数opengl) 一般而言:
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) 一般而言:
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();
我通常不会渲染场景两次:)。首先,我将其渲染到FBO以仅使用顶点XYZ位置填充深度纹理(因此基本上它是“Z-prepass”),然后才正常渲染。无论如何,没有一个教程不说任何关于
glActiveTexture
,它似乎是通过在同一着色器程序中发送不同的纹理来负责的。我已将深度纹理设置为GL_TEXTURE1
,并在渲染FBO时将其绑定,效果良好!非常感谢您的代码!抱歉,我没有足够的声誉:(我通常不会渲染场景两次:)。首先,我将其渲染到FBO以仅使用顶点XYZ位置填充深度纹理(因此基本上它是“Z-prepass”),然后才正常渲染。无论如何,没有一个教程不说任何关于glActiveTexture
,它似乎是通过在同一着色器程序中发送不同的纹理来负责的。我已将深度纹理设置为GL_TEXTURE1
,并在渲染FBO时将其绑定,效果良好!非常感谢您的代码!对不起,我没有足够的声誉:(