3D精灵,写出正确的深度缓冲信息

时间:2011-12-08 07:15:25

标签: opengl-es opentk

我正在使用Monotouch和openTK为iOS编写粒子引擎。我的方法是投影每个粒子的坐标,然后在这个屏幕位置写一个正确缩放的纹理矩形。

它工作正常,但我无法计算正确的深度值,因此精灵将正确透支并被场景中的3D对象透支。

这是我今天使用的代码:

//d=distance to projection plane
float d=(float)(1.0/(Math.Tan(MathHelper.DegreesToRadians(fovy/2f))));
Vector3 screenPos=Vector3.Transform(ref objPos,ref viewMatrix, out screenPos);
float depth=1-d/-screenPos.Z;

然后我在屏幕坐标处绘制一个三角形条,我将上面计算的深度值作为z坐标。

结果几乎是正确的,但并不完全正确。我想我需要以某种方式考虑近和远剪裁平面(在我的情况下接近1和远是10000),但我不确定如何。我尝试了各种方法和算法,却没有得到准确的结果。

我很欣赏这方面的一些帮助。

1 个答案:

答案 0 :(得分:1)

你真正想要做的是获取你的源头位置并通过模型视图和投影或者你已经设置的任何东西,如果你没有使用固定的管道。假设您已使用其中一个标准调用来设置堆栈,例如glFrustum,并以其他方式保留标识,那么您可以直接从手册页获取相关公式。因此,请直接从您转换为:

z_clip = -( (far + near) / (far - near) ) * z_eye - ( (2 * far * near) / (far - near) )
w_clip = -z

然后,最后:

z_device = z_clip / w_clip;
编辑:当你在ES 2.0中工作时,你实际上可以完全避免这个问题。提供几何体以渲染为GL_POINTS并在顶点着色器中执行法线变换,但将gl_PointSize设置为您想要该点的像素大小。

在片段着色器中,您可以阅读gl_PointCoord以获取每个片段的纹理坐标,这些片段是您的点的一部分,如果您不想只使用一种颜色,则可以绘制点精灵。