2010-05-18 30 views

回答

11

首先关闭深度写/测试(你不需要与关闭深度测试打扰,如果你先画天空盒和清除深度缓存):

glDisable(GL_DEPTH_TEST); 
glDepthMask(false); 

然后移动相机原点并旋转模型视图矩阵的逆:

// assume we're working with the modelview 
glPushMatrix(); 

// inverseModelView is a 4x4 matrix with no translation and a transposed 
// upper 3x3 portion from the regular modelview 
glLoadMatrix(&inverseModelView); 

现在,请你天空盒,把深度回写上:

DrawSkybox(); 

glPopMatrix(); 
glDepthMask(true); 
glEnable(GL_DEPTH_TEST); 

您可能想要使用glPush/PopAttrib()来确保在绘制天空盒之后您的其他状态也能正确设置(确保在必要时关闭照明或混合等功能)。

您应该在绘制任何东西之前这样做,以便所有颜色缓冲区写入发生在天空盒顶部。

+7

天空盒作为第一件事呈现是浪费一堆带宽的最佳方式。 – Bahbar 2010-05-19 07:37:53

+4

不过,我认为OP并不关心性能。最后绘制天空盒比较复杂,因为你必须确保你已经正确地处理了透明和远距离的物体,而不是夹在天空盒中。在进行工作实施后,应该对早期Z测试进行优化。 – 2010-05-19 12:55:17

1

没有无限。天空盒只是一个纹理盒子,中间是0,0,0。 这是一个简短的啧啧:link text

+0

天才。你必须在无限远处(无深度)绘制它,因为除了天空盒之外没有任何东西可以远离它。下次做你的研究。 – Tara 2013-06-27 14:08:30

0

我能想到的最好的方法是在第一遍(或图层)上绘制它,然后只清除深度缓冲区。之后,在另一个通道中画出其余的场景。这样天空盒将永远保持在场景后面。只记得两次使用相同的相机,并以某种方式将天空盒与相机对齐。

3

首先,清除缓冲区。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

然后,保存您当前的模型视图矩阵并加载标识。

glPushMatrix(); 
glLoadIdentity(); 

然后渲染你的天空盒。

Skybox.render(); 

然后,清除深度缓存,并呈现

glClear(GL_DEPTH_BUFFER_BIT); 

OtherStuff.render(); 

glutSwapBuffers(); 
2

唯一的问题与绘制天空盒是第一个正常继续,是你的像素着色器将在天空盒的每个像素执行。稍后将被其他物体覆盖。你最好的选择是渲染所有不透明物体,然后渲染你的天空盒。这样,只有通过z缓冲区测试的像素才能执行天空像素着色器。