0

我正在使用 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),但我不确定如何。我尝试了各种方法和算法,但没有得到准确的结果。

我很感激这方面的一些帮助。

4

1 回答 1

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作为点的一部分的每个片段的纹理坐标,如果您不想要单一颜色,则允许您绘制点精灵。

于 2011-12-08T14:30:27.017 回答