OpenGL:如何将天空盒放置在无限远处?

7

我想知道如何使天空盒看起来像无限远?我知道这与深度有关,但我不知道要禁用或启用的确切内容?

5个回答

12

首先,关闭深度写入/测试(如果您首先绘制天空盒并清除深度缓冲区,则无需担心关闭深度测试):

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
4
确实,然而我认为原帖作者现在并不关心性能问题。将天空盒最后绘制更加复杂,因为你必须确保已经正确处理了透明和远处的物体,以免与天空盒发生剪切。在有一个可工作的实现之后,应该进行针对早期-Z 测试的优化。 - Ron Warholic

3

首先,清空缓冲区。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

接下来,保存当前的模型视图矩阵并加载单位矩阵。

glPushMatrix();
glLoadIdentity();

然后渲染你的天空盒。
Skybox.render();

然后,清除深度缓冲并继续常规渲染。

glClear(GL_DEPTH_BUFFER_BIT);

OtherStuff.render();

glutSwapBuffers();

2

在绘制天空盒时唯一的问题是,你的像素着色器将为天空盒中的每个像素执行。但后面会被世界中其他对象覆盖。你最好的选择是先渲染所有不透明物体,然后再渲染你的天空盒。这样,天空盒的像素着色器仅对通过z缓冲区测试的像素执行。


1

不存在无限。天空盒只是一个带有纹理的盒子,通常在中心点0,0,0。 这里有一个简短的教程:链接文本


天才。你必须将它绘制在无限远处(没有深度),因为没有比天空盒更远的东西了。下次要做好研究。 - Tara

0
我能想到的最好方法是先在第一次(或层)上绘制它,然后仅清除深度缓冲区。之后,在另一次通行中绘制场景的其余部分。这样,天空盒将始终保持在场景的“后面”。只需记住在两次通行中使用相同的摄像机,并将天空盒以某种方式捕捉到摄像机上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接