【问题标题】:OpenTK incorrect culling of objectsOpenTK 不正确地剔除对象
【发布时间】:2015-08-18 18:31:04
【问题描述】:

我最近使用 OpenTK 使用 C# 和 OpenGL 制作了一个应用程序。为了提高性能,我集成了一个截锥体剔除系统,但由于某些原因,对象没有被正确剔除。我的意思是,它不是很好地显示所有可见对象,而是剔除随机对象,当我旋转相机时,一些对象会出现和消失。我知道这很正常,但不是在我应该看到他们的时候。实际的截锥体剔除代码是我在其他方面使用的工作 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;
    }

我在其他一些帖子中看到人们手动将视图和投影矩阵相乘,但我不确定这是问题的原因。我做错了什么? 谢谢

【问题讨论】:

    标签: c# opentk frustum culling


    【解决方案1】:

    尝试使用我的代码实现https://github.com/ALEXGREENALEX/LED_Engine/tree/master/LED_Engine/LED_Engine(“FrustumCulling.cs”和“Game.cs”中的 Draw 调用):

    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 矩阵,但实际上那只是 View 矩阵):

    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 );
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多