OpenGL精灵场景,使用带有透视投影的z-buffer而不会失真。可能?

时间:2014-10-07 19:28:30

标签: opengl-es-2.0 sprite perspective depth-buffer

我正在研究一些基于精灵的游戏。对于z排序精灵,基本上有替代品 1)按正确的顺序绘制 - 对于批处理来说可能很麻烦 2)使用正交投影和深度测试 - 半透明可能很麻烦

我赞成2)但是我想保持透视投影以允许一些简单的3D动画。卡片在3d等中翻转。如果我这样做,z缓冲区差异可能/将导致精灵缩放,因为物体与相机的距离不同。
我想过根据它们的距离缩放精灵以撤消投影。但随后我会在当时的“非平面”2D场景中干扰3D动画对象。

我想这是理智的方式,去寻找一个正交的2D场景,并在第二步做罕见的3D动画,在它上面放置“克隆”对象。但也许有人有不同的想法?

<小时/>

mikkokoos的回答导致了一个解决方案。通过额外的深度值,顶点着色器可以调整剪辑空间中所有顶点的z坐标,以将它们推送到不同的深度层。真正的三维坐标可以保持在z = 0。剪辑空间的更改消除了透视问题,因此可以在场景中使用透视投影 为了允许不同于垂直于精灵平面的摄像机角度,而不是将精灵顶点推到固定层,它们应该通过“layerOffset * layerIdx”进行调整。因此,对于每一层,顶点都会被推到靠近摄像机的位置。

注意:对于固定层,找到正确的剪辑空间坐标可能非常棘手,因为xy平面不一定在中心。

开放性问题:剪辑空间的分辨率?剪辑空间中最小的坐标差异?推动的精灵和真正的3D元素之间可能存在干扰?为了防止平面精灵过度绘制3d对象,应使用最大使用的图层偏移量推送所有非精灵平面对象。从相机前面的可用空间计算层偏移可能是个好主意。

已实现:精灵在透视投影3D场景中的2d平面上进行组织。基于碎片深度遮挡精灵,在着色器中计算。绘图仍然可以在纹理批次中完成。

注2:我仍然考虑进行两次批量绘制运行。第一个用于调整深度的2d精灵,第二个用于精灵或没有“附着”到精灵平面的物体。清除中间的深度缓冲区并添加不可见的精灵平面以进行裁剪。 (如果舞台后面没有任何物品允许)
图片:
http://www.imagebam.com/image/109f6e356918267
http://www.imagebam.com/image/a2085f356918275

2 个答案:

答案 0 :(得分:2)

您可以使用透视投影渲染所有精灵并具有均匀浮动&#34;深度&#34;对于每个将替换顶点着色器末尾的gl_Position.z:

gl_Position.z=(u_zOffset-1.0)*gl_Position.w;

这将使#34;变平&#34;网格,所以如果您的网格更复杂并且取决于使用的DepthFunc,您可能希望改为使用范围。 (可见范围从-1到1):

gl_Position.z=((1.0+(gl_Position.z/gl_Position.w))*u_zRange+u_zOffset-1.0)*gl_Position.w;

其中u_zRange是2f /(number_of_layers)而u_zOffset是u_zRange * layer_id。第0层是最接近的。

编辑:摘要:将所有内容放在距离相机相同距离的MVP矩阵中,然后修改顶点着色器中的Z值,以便在屏幕上对它们进行排序。

答案 1 :(得分:1)

我不知道您正在开发什么类型的游戏,以及后续内容如何适合您的系统,但您是否考虑过使用两个投影的可能性?

如果您需要正常显示的对象与您需要在3D中制作动画的对象不同,为什么不使用第一个的ortographic投影和第二个的透视投影?

实际上,即使它们重叠,你也可能会采用某种技巧(如果不是一个简单的线性过渡......),在使用适当的参数(你的里程数可能)之前,用动画之前的透视图取代ortographic投影。然而,与此不同,我承认我没有做数学......)。

也许这是一个疯狂的想法,但我希望这有帮助