使用BackMaterial,我們可以定義3D物體的內部材質(或者說是背面),比如,我們定義一個四方體容器,外面現實的是普通材質,裡面的則是內部材質。比如,紅色的是內部材質:
GeometryModel3D.BackMaterial預設是null,所以如果不定義他的話,背面的材質是不會顯示,上面的程式則會運行成這樣:
定義材質很簡單,設定GeometryModel3D.Material屬性和BackMaterial,放置任何一個繼承與Material類型的對象,這裡就以最普通的DiffuseMaterial做示範:
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Green"/>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Red"/>
</GeometryModel3D.BackMaterial>
很簡單,痛點則在於怎樣正確定義。
WPF MeshGeometry3D中,逆時針定義的三角形代表著正面,也就是說會被Material屬性填充,而他的背面會被BackMaterial填充。上面中的3D圖形是4個面,每個面4個點,這樣一共16個點,分別將外面的面中的三角形逆時針定義。注意要在立體空間內將每個對外的面的三角形都逆時針定義或許考驗你的空間想象力,做個簡單的示範圖如下:
這樣的話,先在Positions中定義的所有點,然後根據三角形的定義方向再定義TriangleIndices就可以了。代碼:
<MeshGeometry3D Positions="-1 1 1, 1 1 1, -1 -1 1, 1 -1 1, -1 1 -1, 1 1 -1, -1 -1 -1, 1 -1 -1
1 1 1, 1 1 -1, 1 -1 1, 1 -1 -1, -1 1 1, -1 1 -1, -1 -1 1, -1 -1 -1"
TriangleIndices="0 2 1, 1 2 3, 5 6 4, 5 7 6
8 10 9, 9 10 11, 13 14 12, 13 15 14"/>
這樣就得到了上面的3D圖形(文章下面有完整的XAML代碼)。
如果我們把一個三角形改成順時針定義的,比如第一個點,把TriangleIndices中的逆時針定義的0 2 1點改成1 2 0。第一個三角形則會被填充成BackMaterial,結果成了:
完整的代碼:
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="-2.5 2.5 5" LookDirection="0.5 -0.5 -1"/>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Direction="1 0 -7"
Color="White"/>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-1 1 1, 1 1 1, -1 -1 1, 1 -1 1, -1 1 -1, 1 1 -1, -1 -1 -1, 1 -1 -1
1 1 1, 1 1 -1, 1 -1 1, 1 -1 -1, -1 1 1, -1 1 -1, -1 -1 1, -1 -1 -1"
TriangleIndices="0 2 1, 1 2 3, 5 6 4, 5 7 6
8 10 9, 9 10 11, 13 14 12, 13 15 14"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Green"/>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Red"/>
</GeometryModel3D.BackMaterial>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>