【问题标题】:Sphere image texture is distorted by shadow map - OpenGL球体图像纹理被阴影贴图扭曲 - OpenGL
【发布时间】:2014-12-18 17:05:33
【问题描述】:

我正在使用固定功能管道而不是着色器在 OpenGL 中进行阴影映射。我已经设法很好地实现了阴影贴图,但是在投射阴影的东西上没有纹理。

当我在球体渲染之前将纹理添加到球体时,它会出现扭曲。我可以在我的光源周围移动,它会根据光源的位置或多或少地扭曲它。

这可能是什么原因?

这是我的 glLightfv(GL_LIGHT1, GL_DIFFUSE, white); glLightfv(GL_LIGHT1, GL_SPECULAR, 白色);

//Calculate texture matrix for projection
//This matrix takes us from eye space to the light's clip space
//It is postmultiplied by the inverse of the current view matrix when specifying texgen
static MATRIX4X4 biasMatrix(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);    //bias from [-1, 1] to [0, 1]
MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;

//Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);

glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);

glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);

//Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glEnable(GL_TEXTURE_2D);

//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);

//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);

//Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.99f);
glEnable(GL_ALPHA_TEST);
glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
world->textured = true;
renderObjects();

sun->center = Vertex(lightX, lightY, lightZ);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
  glColor3f(1,1,0);
  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;  
  glTranslatef(sun->center.x, sun->center.y, sun->center.z);
  sun->lighting = false;
  sun->z = -lightZ +1;
  sun->render();
  glColor3f(1, 1, 1);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);

//Disable textures and texgen
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
//Restore other states
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);

//reset matrices
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
update();

渲染对象:

void Widget::renderObjects()
{
  glPushMatrix();
    glColor4f(1.0, 1.0, 1.0, 1.0);
    glPushMatrix();
      //glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission); 
      //glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); 
      arcBall->q.rotate();
      world->render();
      glPushMatrix();
        torso->frame = frame;
        torso->draw();
        glPushMatrix();
          renderParticles();
        glPopMatrix();
      glPopMatrix();
    glPopMatrix();
  glPopMatrix();
}

还有,这也是我的第一次和第二次传球。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
lightPosition = VECTOR3D(lightX, lightY, lightZ);
glLoadIdentity();
gluLookAt(  lightPosition.x, lightPosition.y, lightPosition.z,
            0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);




glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);

//Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapSize, shadowMapSize);

//Draw back faces into the shadow map
glCullFace(GL_FRONT);

//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
//Draw the scene
renderObjects();

//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

//restore states
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);


//2nd pass - Draw from camera's point of view
glClear(GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(cameraProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(cameraViewMatrix);

glViewport(0, 0, windowWidth, windowHeight);

//Use dim light to represent shadowed areas
glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));
glLightfv(GL_LIGHT1, GL_AMBIENT, white*0.2f);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white*0.2f);
glLightfv(GL_LIGHT1, GL_SPECULAR, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);

renderObjects();

【问题讨论】:

  • 漫反射纹理是什么意思?当我进行第一次/第二次渲染时,我不渲染我的纹理。只有第三遍是我加载它们,然后在对象上绑定和渲染它们。
  • 在评论中解释的工作量太大,所以我用一些伪代码写了一个答案。
  • 我添加了一些代码来向您展示我目前为最终渲染过程所做的工作。

标签: c++ opengl 3d geometry shadow


【解决方案1】:

由于您使用固定功能管道执行此操作,我想您正在使用纹理矩阵(每个纹理图像单元状态)。

当您尝试从常规纹理中采样时,您确定纹理矩阵设置正确吗?在我看来,您对漫反射纹理使用的矩阵与用于阴影贴图的矩阵相同。通常,在对除阴影贴图以外的所有内容进行采样时,您会需要恒等矩阵。

考虑以下示例:

glActiveTexture (GL_TEXTURE0);
glMatrixMode    (GL_TEXTURE);
glLoadMatrixf   (shadow_matrix);

glBindTexture   (shadow_map);

// Draw shadow pass

glBindTexture   (diffuse_map);

// Draw the base diffuse pass

在此示例中,第二次绘制仍然受到您必须为阴影贴图加载的矩阵的影响。您可以通过两种方式解决:

  1. 专用纹理图像单元对阴影贴图进行采样
  2. 应用阴影贴图后推送/弹出或加载身份纹理矩阵

【讨论】:

  • 当我加载单位矩阵时,我的光照会消失。
  • @Gentatsu:我最初的假设是错误的……您使用的是基于纹理矩阵的glTexGen (...)。这是一个非常相似的概念,但要解决这个问题,您需要调用glDisable (GL_TEXTURE_GEN_S)glDisable (GL_TEXTURE_GEN_T)glDisable (GL_TEXTURE_GEN_R)glDisable (GL_TEXTURE_GEN_Q) 你的影子传球之后。
  • 啊。我刚刚注意到一些事情。我的纹理一次只显示一部分纹理。
  • 嗯,这让我恢复了光线,但现在我的阴影不显示了。我现在在渲染我的对象之前调用了禁用。
  • @Gentatsu:实际上需要在renderObjects () 内部完成。我假设您正在讨论的三个通道是在该函数中完成的。第一遍需要启用纹理坐标生成,但第三遍(可能是第二遍)不需要。如果你能展示renderObjects (...) 的实现,那会有所帮助。
猜你喜欢
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多