OpenGL中的照明问题

时间:2008-11-07 14:07:36

标签: opengl

我有一个三角形网格没有纹理,但是设置颜色(蓝色)和alpha(0.7f)。此网格是生成的运行时间,法线是正确的。我发现随着灯光的亮起,我的物体颜色会随着它在水平面上移动而改变。此外,照明看起来不正确。当我绘制这个对象时,这就是代码:

glEnable( GL_COLOR_MATERIAL );
float matColor[] = { cur->GetRed(), cur->GetGreen(), cur->GetBlue(), cur->GetAlpha() };
float white[] = { 0.3f, 0.3f, 0.3f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matColor);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);

我注意到的另一个奇怪的事情是,当我禁用GL_FRONT_AND_BACK并仅使用GL_FRONT或GL_BACK时,灯光会失败。 这是我的灯光设置(在渲染器开始时完成一次):

m_lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
m_lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
m_lightPosition[] = { 0.0f, 1200.0f, 0.0f, 1.0f };

glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);
编辑:我已经做了很多工作以使法线“更”正确(因为我自己生成表面),但是对象的颜色仍然会根据它来改变。为什么是这样? openGL是否有一些我不知道的特殊环境混合? 编辑:变色是因为先前的纹理在纹理堆栈上,即使它没有被绘制,glMaterialfv也在混合它。

8 个答案:

答案 0 :(得分:1)

如果在禁用GL_FRONT_AND_BACK时灯光失败,则可能会翻转法线。

答案 1 :(得分:1)

你能发布初始化OpenGL的代码吗?你说所有其他网格都画得很完美吗?你是否同时渲染它们?

答案 2 :(得分:1)

@ssese史密斯:

Z-testing对透明三角形没有帮助,你也需要每个三角形的alpha排序。如果您的对象在任何时候都可能有重叠的三角形面向相机(凹面对象),您必须首先绘制最远的三角形,以确保正确执行混合,因为Z测试不考虑透明度。 考虑这两个重叠(和透明)的三角形,并考虑在绘制小的重叠区域时会发生什么,有或没有Z测试。你可能会得出这样的结论,即绘图顺序确实很重要。透明度很糟糕:P

    /\    /\
   /  \  /  \
  /    \/    \
 /     /\     \
/_____/__\_____\

我不相信这是你的问题,但在处理部分透明的物体时需要考虑alpha分类。

答案 3 :(得分:0)

如果您的三角形是alpha混合的,那么您是否需要通过相机的z顺序对面部进行排序?否则,您可能会在对象背面的正面顶部渲染一个面。

答案 4 :(得分:0)

@sebastion: 多次绘制调用,每个对象获取一个glDrawArrays。有些是纹理的,有些是有色的,都有法线。 gl init代码是:     glMatrixMode(GL_MODELVIEW);

// Vertices!
glEnableClientState(GL_VERTEX_ARRAY);

// Depth func
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_LESS );

// Enable alpha blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, m_lightAmbient);
glLightfv(GL_LIGHT0, GL_SPECULAR, m_lightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition);

// Culling
glDisable( GL_CULL_FACE );
// Smooth Shading
glShadeModel(GL_SMOOTH);

m_glSetupDone = true;

之后我有一些相机设置,但这完全是标准的,投影模式,视锥体,模型视图,看看,翻译。

答案 5 :(得分:0)

您确定您的法线正常化吗? 如果没有,你通过glNormal调用指定法线,你可以尝试让OpenGL为你做标准化,记住这应该避免,但你可以测试它:

glEnable(GL_NORMALIZE);

这样你就告诉OpenGL重新缩放通过glNormal提供的所有法线向量。

答案 6 :(得分:0)

我在地形显示上遇到了透明性问题,从某个角度看,斜坡似乎是透明的。仅在着色器中启用了照明时才发生。原来我没有打开深度测试,并且从某个角度看该地形被其他地形覆盖并显示为半透明。

TLDR;检查是否启用了深度测试,如果涉及照明,则将其禁用可能会产生类似透明的效果。 https://learnopengl.com/Advanced-OpenGL/Depth-testing

答案 7 :(得分:0)

发现颜色变化是因为先前的纹理位于纹理堆栈上,即使未绘制,glMaterialfv也在与之混合。