首页 文章

C#Wpf 3D组合导致照明问题的模型

提问于
浏览
1

我正在研究一个简单的3D模型查看器,我需要能够支持非常大的模型(100,000个三角形)并在旋转相机时运动平稳 .

为了优化绘图而不是在多边形中创建每个线段的GeometryModel3D,我想使用顶点和三角形索引的完整列表 . 加速是惊人的,但现在灯光搞砸了 . 每个三角形现在都有自己的阴影 .

我认为这个问题与法线有关,如果我手动将所有法线设置为Vector3(0,0,1),那么我会得到均匀照明 . 但是当我试图看到模型的侧面或反面时它是黑暗的 . 我还尝试使用公式来计算每个三角形的法线,但结果是相同的:一个大型模型会搞砸,单独的模型看起来会很好 . 那么也许这不是一个正常的问题?

我很好奇为什么当模型分开时一切正常并且通过组合模型会导致问题 .

Image Showing the Issue

polyMesh对象包含一堆面,它们包含它使用的顶点索引 . 三角形或四边形 . polyMesh具有所有顶点信息 .

var models = new Model3DCollection();
        var brush = new SolidColorBrush(GetColorFromEntity(polyMesh));
        var material = new DiffuseMaterial(brush);

        foreach (var face in polyMesh.FaceRecord)
        {
            var indexes = new Int32Collection();

            if (face.VertexIndexes.Count == 4)
            {
                indexes.Add(face.VertexIndexes[0]);
                indexes.Add(face.VertexIndexes[1]);
                indexes.Add(face.VertexIndexes[2]);

                indexes.Add(face.VertexIndexes[2]);
                indexes.Add(face.VertexIndexes[3]);
                indexes.Add(face.VertexIndexes[0]);
            }
            else
            {
                indexes.Add(face.VertexIndexes[0]);
                indexes.Add(face.VertexIndexes[1]);
                indexes.Add(face.VertexIndexes[2]);
            }

            MeshGeometry3D mesh = new MeshGeometry3D()
            {
                Positions = GetPoints(polyMesh.Vertices),
                TriangleIndices = indexes,
            };

            GeometryModel3D model = new GeometryModel3D()
            {
                Geometry = mesh,
                Material = material,
            };

            models.Add(model);
        }

        return models;

如果我将Mesh和Geometry从循环中取出并创建一个大的网格就会出错 .

var models = new Model3DCollection();
        var brush = new SolidColorBrush(GetColorFromEntity(polyMesh));
        var material = new DiffuseMaterial(brush);
        var indexes = new Int32Collection();

        foreach (var face in polyMesh.FaceRecord)
        {
           //Add indices as above (code trimmed to save space.)
           indexes.Add(face.VertexIndexes[0]);               
        }

        MeshGeometry3D mesh = new MeshGeometry3D()
        {
            Positions = GetPoints(polyMesh.Vertices),
            TriangleIndices = indexes,
        };

        GeometryModel3D model = new GeometryModel3D()
        {
            Geometry = mesh,
            Material = material,
        };

        models.Add(model);

        return models;

其他重要细节:模型不仅仅是一个平坦的表面,它是一种复杂的道路模型 . 我无法显示整个模型,也无法提供导入方式的代码 . 我正在使用HelixToolKit进行相机控制和诊断 .

视口代码:

<h:HelixViewport3D ZoomExtentsWhenLoaded="True" IsPanEnabled="True" x:Name="ViewPort" IsHeadLightEnabled="True">
        <h:HelixViewport3D.DefaultCamera>
            <!--フリッカー回避方法 This code fixes a flicker bug! Found at http://stackoverflow.com/a/38243386 -->
            <PerspectiveCamera NearPlaneDistance="25"/>
        </h:HelixViewport3D.DefaultCamera>
        <h:DefaultLights/>
    </h:HelixViewport3D>

设置背面材料不会改变任何东西 . 我希望我只是一个白痴,并且因为我是3D新手而错过了一些明显的东西 .

1 回答

  • 1

    最后我自己修好了 .

    归结为对Wpf3D(或一般3D)的了解不够 .

    如果在组合模型中重用顶点,则应用smoth着色 . 平滑阴影在平面上看起来如此糟糕的原因是它正在对整个3D模型应用阴影 . 我的每个多面都是3D形状 . 墙上的每个部分是具有~6个面的不同聚合物 . (前,上,下,左,右,后) .

    当每个顶点位置都是唯一的时,即使组合模型,问题也会消失 . 当分开时,每个模型都有一个位置的副本,它们是唯一的 . 找到答案来自:

    http://xoax.net/blog/automatic-3d-normal-vector-calculation-in-c-wpf-applications/

相关问题