OpenTK对象剔除错误
本文关键字:错误 对象 OpenTK | 更新日期: 2023-09-27 18:08:29
我最近用c#和OpenGL使用OpenTK做了一个应用程序。为了提高性能,我集成了一个截锥体剔除系统,但由于某些原因,对象无法正确剔除。我的意思是,它不是很好地显示所有可见对象,而是随机剔除对象,当我旋转摄像机时,一些对象出现和消失。我知道这很正常,但不是我该去看他们的时候。实际的截锥体剔除代码是我在其他地方使用的c++/DirectXMath代码的c#移植。
下面是我创建六个截锥体平面的方法:
// Create a new view-projection matrices.
var vp = viewMatrix * projMatrix;
// Left plane.
frustumPlanes[0] = new Vector4
{
X = vp.M14 + vp.M11,
Y = vp.M24 + vp.M21,
Z = vp.M34 + vp.M31,
W = vp.M44 + vp.M41
};
// Right plane.
frustumPlanes[1] = new Vector4
{
X = vp.M14 - vp.M11,
Y = vp.M24 - vp.M21,
Z = vp.M34 - vp.M31,
W = vp.M44 - vp.M41
};
// Top plane.
frustumPlanes[2] = new Vector4
{
X = vp.M14 - vp.M12,
Y = vp.M24 - vp.M22,
Z = vp.M34 - vp.M32,
W = vp.M44 - vp.M42
};
// Bottom plane.
frustumPlanes[3] = new Vector4
{
X = vp.M14 + vp.M12,
Y = vp.M24 + vp.M22,
Z = vp.M34 + vp.M32,
W = vp.M44 + vp.M42
};
// Near plane.
frustumPlanes[4] = new Vector4
{
X = vp.M13,
Y = vp.M23,
Z = vp.M33,
W = vp.M43,
};
// Far plane.
frustumPlanes[5] = new Vector4
{
X = vp.M14 - vp.M13,
Y = vp.M24 - vp.M23,
Z = vp.M34 - vp.M33,
W = vp.M44 - vp.M43
};
// Normalize all the planes.
for (int i = 0; i < 6; i++)
frustumPlanes[i] = Vector4.Normalize(frustumPlanes[i]);
检查球体是否应该被剔除:
public bool CullSphere(Vector3 position, float radius = 0.0f)
{
foreach (var plane in frustumPlanes)
{
// Verify if the point is behind the plane.
if (Vector3.Dot(plane.Xyz, position) + plane.W < -radius)
return true;
}
return false;
}
我在其他一些帖子上看到人们手动乘法视图和投影矩阵,但我不确定这是问题的原因。我做错了什么?由于
尝试使用我的代码实现https://github.com/ALEXGREENALEX/LED_Engine/tree/master/LED_Engine/LED_Engine ("FrustumCulling.cs"和Draw call in "Game.cs"):
static void Draw(Mesh m)
{
m.CalculateMatrices(MainCamera);
FrustumCulling.ExtractFrustum(MainCamera.GetViewMatrix() * MainCamera.GetProjectionMatrix());
float Scale = Math.Max(m.Scale.X, Math.Max(m.Scale.Y, m.Scale.Z));
if (FrustumCulling.SphereInFrustum(m.Position, m.BoundingSphere.Outer * Scale))
for (int i = 0; i < m.Parts.Count; i++)
// ...
Draw(m, m.Parts[i]);
}
公立小学1)提取截锥体后,必须检查与缩放对象的相交(取skale的最大值并乘以外部BoundingSphere半径)。
2)在一些旧的例子中,我们可以在ExtractFrustum函数中看到MVP矩阵(如:http://www.codesampler.com/oglsrc/oglsrc_12.htm#ogl_frustum_culling)。那是错误的名字!他们使用旧的API和模型矩阵,在这个计算是单位矩阵(他们称之为MV - ModelView矩阵,但实际上只是视图矩阵):
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
updateViewMatrix();
calculateFrustumPlanes();
void calculateFrustumPlanes(void)
{
float p[16]; // projection matrix
float mv[16]; // **VIEW MATRIX!!!**
float mvp[16]; // **View-Projection matrix!!!**
glGetFloatv( GL_PROJECTION_MATRIX, p );
glGetFloatv( GL_MODELVIEW_MATRIX, mv );
//...
}