球体图像纹理被阴影贴图 - OpenGL 扭曲
Sphere image texture is distorted by shadow map - OpenGL
我正在使用固定函数管道而不是着色器在OpenGL中进行阴影映射。我已经设法很好地实现了阴影贴图,但是在投射阴影的东西上没有纹理。
当我在渲染之前将纹理添加到球体时,它看起来很失真。我可以在我的光源周围移动,它会根据光源的位置或多或少地扭曲它。
造成这种情况的可能原因是什么?
这是我的glLightfv(GL_LIGHT1,GL_DIFFUSE,白色(; 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();
由于您使用的是固定函数管道来执行此操作,因此我想您使用的是纹理矩阵(每个纹理图像单元的状态(。
当您尝试从常规纹理中采样时,您确定纹理矩阵设置正确吗?在我看来,您对漫反射纹理使用的矩阵与用于阴影贴图的矩阵相同。通常,在对除阴影贴图以外的所有内容进行采样时,您会想要单位矩阵。
请考虑以下示例:
glActiveTexture (GL_TEXTURE0);
glMatrixMode (GL_TEXTURE);
glLoadMatrixf (shadow_matrix);
glBindTexture (shadow_map);
// Draw shadow pass
glBindTexture (diffuse_map);
// Draw the base diffuse pass
在此示例中,第二次绘制仍受到您必须为阴影贴图加载的矩阵的影响。您可以通过两种方式解决此问题:
- 专用于纹理图像单元对阴影贴图进行采样
- 应用阴影贴图后推送/弹出或加载标识纹理矩阵
相关文章:
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 了解 GLM- openGL 中的相机转换
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- OpenGL大的3D纹理(>2GB)非常慢
- OpenGl glm rotate
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- OpenGL在启用深度测试时不会丢弃我的碎片
- OpenGL相机和相机空间转型的困惑
- OpenGL将纹理四边形渲染为(0,0)
- OpenGL 和 GLM 矩阵无法正确扩展,总是按比例缩小
- 发布旋转矩阵(openGL/glm)
- 如何在Visual Basic中使用矩形函数OpenGL绘制矩形
- 无法使用VAO和EBO(openGL)绘制多个对象
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- OpenGL 16 位模板缓冲区?
- 将QOpenGLWidget子类转换为使用Metal而不是OpenGL的子类是否可行?
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 在 openGL 中多次绑定缓冲区
- 球体图像纹理被阴影贴图 - OpenGL 扭曲