我想构建一个正交投影,使我的太阳阴影贴图看起来正确。不幸的是,代码没有像使用常规透视投影那样实现期望的结果。这是我设置投影矩阵的代码:
glViewport (0, 0, (GLsizei)shadowMap.x, (GLsizei)shadowMap.y);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
//suns use this
glOrtho(0, shadowMap.x, 0, shadowMap.y, 0.1,1000.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
据我所知,这应该是正确的。但是,经过快速调试渲染后,我注意到场景在屏幕的一小部分呈现。经过一些实验,我发现改变glOrtho中的shadowMap值使它覆盖整个纹理,但它确实放大了。在我的视角投影中,我使用0.1和1000.0来近距离和远距离,我已经尝试了这些和它确实会改变结果,但仍然无法获得理想的结果。我得到正确结果的唯一时间是使用shadowMap.x和shadowMap.y保存值,但就像我说的那样,它的渲染非常小。
我在这里做错了什么?我读过的所有内容都说初始代码是正确的。
编辑: 显然不清楚这是用于阴影贴图传递,常规传递是用透视渲染的,并且很好。
答案 0 :(得分:0)
阴影映射是多遍算法。 你正在考虑第一次通过(第1点)。
将场景窗体光源视图渲染为深度纹理
从相机视图渲染场景并启用深度纹理投影映射。
然后将当前片段xy +深度转换为光投影坐标,并与深度纹理上存储的深度进行比较
如果两个深度相等(或几乎相等),则应将当前片段视为亮起,否则视为阴影。
所以对你的代码来说一切都很好,从这个传递到深度纹理存储深度值,然后进入第2点。
你应该考虑的一件事是你的光线应该覆盖多大的区域(在世界空间中)。通过模型视图上的loadidentity,您将尝试覆盖1个世界单位x 1世界单位区域,仅为您点亮。
我们希望将它沿Z投影到球体上。
glVieport(0,0,256,256); glMatrixMode(GL_PROJECTION); glLoadidentity(); glOrtho(-2.5,2.5,-2.5,2.5,-1000,1000); glMatrixMode(GL_MODELVIEW); glLoadidentity(); //翻转z,我们从obove投射光 glRotate(1,0,0,180);
答案 1 :(得分:0)
我不知道你在哪里设置了光模型视图矩阵。您可以使用以下代码渲染阴影贴图:
double* getOrthoMVPmatrix(vector3 position,vector3 lookat,
GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble nearVal, GLdouble farVal)
{
glPushMatrix();
double projection[16];
double modelView[16];
double *matrix = new double [16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( left, right, bottom, top, nearVal, farVal) ;
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
gluLookAt(position.x,position.y,position.z,lookat.x,lookat.y,lookat.z,0,1,0);
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glPopMatrix();
matrix = projection*modelView;
return matrix ;
}
void renderShadowMap(void)
{
//"Bind your depth framebuffer"
glViewport(0,0,"Your SM SIZE","Your SM SIZE");
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
double *MVP = getOrthoMVPmatrix( "your light position","your light position" + "your light direction",
-"left","right",
"bottom","top",
"near","far"
) ;
//"call glUseProgram to bind your shader"
// set the uniform MVP we made "
//"Draw your scene "
glViewport(0,0,"screen width","screen height");
}
你需要为double [16]数组创建一个乘法运算符。在我的情况下,我做了一个矩阵类,但按照你的方式做。
不要忘记在绘制真实场景之前调用glCullFace(GL_BACK)并在之后免费获得MVP。