我正在开发一个简单的 3D 模型查看器,我需要能够支持非常大的模型(100,000 + 三角形),并且在旋转相机时能够平滑移动。
为了优化绘图,而不是在多边形网格中创建每个段的 GeometryModel3D,我想使用顶点和三角形索引的完整列表。速度是惊人的,但现在灯光困惑了。现在每个三角形都有自己的阴影。
我认为这个问题与法线有关,如果我手动将所有法线设置为 Vector3(0,0,1),那么我会得到均匀的照明。但是当我尝试查看模型的侧面或反面时,它是黑暗的。我还尝试使用公式来计算每个三角形的法线,但结果是相同的:一个大模型会很困惑,单独的模型看起来不错。那么也许这不是一个正常的问题?
我很好奇为什么当模型分开时一切正常,而组合模型时会出现问题。
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;
如果我将网格和几何体从循环中取出并创建一个大网格,则会出现问题。
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 进行相机控制和诊断。
视口(viewport)代码:
<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>
设置背面 Material 不会改变任何东西。我希望我只是个白痴,错过了一些明显的东西,因为我是 3D 新手。
最佳答案
终于自己解决了这个问题。
归结为对 Wpf3D(或一般 3D?)的了解不够。
如果像组合模型中那样重用顶点,则应用平滑着色。平滑着色在平面上看起来如此糟糕的原因是它正在将着色应用于完整的 3D 模型。我拥有的每个多面都是 3D 形状。墙上的每个部分都是不同的多边形网格,有大约 6 个面。 (前、上、下、左、右、后)。
当每个顶点位置都是唯一的时,即使组合模型,问题也会消失。 当分开时,因为每个模型都有一个位置的副本,所以它们是唯一的。 找到答案:
http://xoax.net/blog/automatic-3d-normal-vector-calculation-in-c-wpf-applications/
关于C# Wpf 3D 组合模型导致光照问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39030483/