我有一个在 3ds Max 中创建的模型。该模型是一个简单的矩形。它的纹理具有重叠的纹理坐标——模型应该并排显示图像文件的右半部分两次。我将此模型导出为 .obj
,并使用 Microsoft Expression Blend 将其转换为 XAML。
我从混合中获取了 MeshGeometry3D
,并使用两种方法将其添加到 Viewport3D
:
- 使用
Viewport2DVisual3D
和Label
作为它的Visual
。将Label
的背景设置为纹理图像。使用此方法,一切都按预期进行。 - 使用
ModelVisual3D
并将GeometryModel3D
作为其Content
。将GeometryModel3D
的 Material 设置为使用图像作为画笔的DiffuseMaterial
。使用此方法时,MeshGeometry3D
的TextureCoordinates
似乎有不同的解释。
下面提供了完整的代码。除了 InitializeComponent()
之外,代码隐藏是空的:
<Window x:Class="TestTextureCoordinates.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<MeshGeometry3D x:Key="geometry"
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1"
Positions="113.8997,102.4171,0 148.9045,102.4171,0 148.9045,148.41161,0 113.8997,148.41161,0 184.5722,102.4171,0 184.5722,148.41161,0 148.9045,148.41161,0 148.9045,102.4171,0"
TextureCoordinates="0.50639999,0.9995 1.0065,0.9995 1.0065,0.00050002337 0.50639999,0.00050002337 1.0022,0.9995 1.0022,0.00050002337 0.5,0.00050002337 0.5,0.9995"
TriangleIndices="0 1 2 0 2 3 4 5 6 4 6 7"/>
<ImageBrush x:Key="brush" ImageSource="img/test.jpg" />
</Grid.Resources>
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="195,125,210" LookDirection="0,0,-1" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
<!-- The first model, using a Viewport2DVisual3D. This works as intended. -->
<Viewport2DVisual3D Geometry="{StaticResource geometry}">
<Viewport2DVisual3D.Visual>
<Label Background="{StaticResource brush}" />
</Viewport2DVisual3D.Visual>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" />
</Viewport2DVisual3D.Material>
</Viewport2DVisual3D>
<!-- The second model, using a ModelVisual3D and GeometryModel3D. The TextureCoordinates do not work as intended. -->
<ModelVisual3D>
<!-- We apply a transform to offset this model from the first model. -->
<ModelVisual3D.Transform>
<TranslateTransform3D OffsetX="90" />
</ModelVisual3D.Transform>
<ModelVisual3D.Content>
<GeometryModel3D Geometry="{StaticResource geometry}">
<GeometryModel3D.Material>
<DiffuseMaterial Brush="{StaticResource brush}" />
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
这是test.jpg
:
这是最终结果。左边是 Viewport2DVisual3D
,它看起来和在 3ds Max 中一样。右侧是 ModelVisual3D
,它似乎以不同方式解释 TextureCoordinates
。
这是怎么回事?由于我正在使用的软件的其他要求,我无法使用 Viewport2DVisual3D
。如何使 GeometryModel3D
正确解释 TextureCoordinates
?
最佳答案
我只需将 ImageBrush
上的 ViewportUnits
设置为 Absolute
:
<ImageBrush x:Key="brush" ImageSource="img/test.jpg" ViewportUnits="Absolute" />
参见 this post ( archive ) 来自 WPF3D 团队博客:
If you don't set TileBrush.ViewportUnits to BrushMappingMode.Absolute, your texture coordinates will be relative to the bounding box of your geometry. For example, let's say you only want half of your texture in v to be mapped to the mesh. In other APIs, you would just range your coordinate from 0.0 -> 0.5. If you do that in WPF3D without setting ViewportUnits to Absolute, it'll still map the entire thing. Essentially any time you don't want one copy of the entire texture you'll want to set Absolute.
关于c# - 为什么 TextureCoordinates 对于 Viewport2DVisual3D 按预期工作,但对于 GeometryModel3D 却不行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7001186/