Opengl 三维正投影

Opengl 三维正投影,opengl,orthographic,Opengl,Orthographic,我想构造一个正交投影,使我的太阳阴影贴图看起来正确。不幸的是,使用常规透视投影时,代码没有达到预期的效果。以下是我设置投影矩阵的代码: 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);

我想构造一个正交投影,使我的太阳阴影贴图看起来正确。不幸的是,使用常规透视投影时,代码没有达到预期的效果。以下是我设置投影矩阵的代码:

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();
据我所知,这应该是正确的。但是,在快速调试渲染后,我注意到场景在屏幕的一小部分进行渲染。经过一些实验后,我发现在Glorth中更改阴影贴图值可以覆盖整个纹理,但它确实放大了。在我的透视投影中,我使用0.1和1000.0来表示“近”和“远”,我已经用它们进行了实验,它确实改变了结果,但仍然没有得到想要的结果。我得到正确结果的唯一时间是使用shadowMap.x和shadowMap.y保留值时,但正如我所说,它的渲染非常小

我做错了什么?我读过的所有内容都表明初始代码是正确的

编辑:
显然,不清楚这是否适用于阴影贴图过程,常规过程是用透视法渲染的,并且很好。

阴影贴图是多过程算法。 您将参照到第一个过程(点1)

  • 将场景从光源视图渲染为深度纹理

  • 从启用深度纹理投影贴图的摄影机视图渲染场景

    • 然后将当前片段xy+深度转换为灯光投影坐标,并与深度纹理上存储的深度进行比较

    • 若两个深度相等(或几乎相等),则当前碎片应视为亮,否则视为阴影

  • 因此,代码一切正常,将此过程中的深度值存储到深度纹理,然后继续第2点

    你们应该考虑的一件事是你们的光应该覆盖多宽的区域(在世界空间中)。使用modelview上的loadidentity,您正试图覆盖1个世界单位x 1个世界单位面积,仅适用于灯光

    • 假设我们有一个半径为5.0的0,0,0的球体
    • 我们的深度纹理为256256 dims
    • 我们想把它沿Z投影到球体上

      glVieport(0,0256256);; glMatrixMode(GL_投影); glLoadidentity(); 格洛托(-2.5,2.5,-2.5,2.5,-10001000); glMatrixMode(GLU模型视图); glLoadidentity(); //翻转z,我们从双簧管投射光线 glRotate(1,0,0180)


    我看不出您在哪里设置灯光模型视图矩阵。可以使用以下代码渲染阴影贴图:

    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");
    
    
    }
    


    您需要为双[16]数组生成一个乘法运算符。在我的例子中,我制作了一个矩阵类,但是按照你的方式来做。
    在绘制真实场景之前,不要忘记调用glCullFace(GL_BACK),然后再释放MVP。

    我知道阴影贴图的工作原理,这是光源投影的代码。我想这在问题中没有说清楚,更新了。另外,您错误地认为此代码是正确的,因为无论通过哪一个过程,场景仍将以错误的投影进行渲染,因此从技术上讲,这是独立于阴影贴图的。更新的最终注释:)我不知道您的最终结果是否是正交的,因为我从未研究过它,但在渲染过程中,几何体会进一步转换为摄影机空间。因为正交投影不使用变换,所以我是否应该从模型视图中忽略摄影机平移?正交将按深度纹理缩放-1+1正方形,这没关系。但您需要缩放modelview矩阵,以便将您的世界适应此投影。如果你不这样做,你的纹理将只包含-1+1正方形。问题不在于如何渲染阴影贴图,而在于如何进行正交投影。