c# - 为什么 TextureCoordinates 对于 Viewport2DVisual3D 按预期工作,但对于 GeometryModel3D 却不行?

标签 c# .net wpf 3d uv-mapping

我有一个在 3ds Max 中创建的模型。该模型是一个简单的矩形。它的纹理具有重叠的纹理坐标——模型应该并排显示图像文件的右半部分两次。我将此模型导出为 .obj,并使用 Microsoft Expression Blend 将其转换为 XAML。

我从混合中获取了 MeshGeometry3D,并使用两种方法将其添加到 Viewport3D:

  1. 使用 Viewport2DVisual3DLabel 作为它的 Visual。将 Label 的背景设置为纹理图像。使用此方法,一切都按预期进行。
  2. 使用 ModelVisual3D 并将 GeometryModel3D 作为其 Content。将 GeometryModel3D 的 Material 设置为使用图像作为画笔的 DiffuseMaterial。使用此方法时,MeshGeometry3DTextureCoordinates 似乎有不同的解释。

下面提供了完整的代码。除了 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:

enter image description here

这是最终结果。左边是 Viewport2DVisual3D,它看起来和在 3ds Max 中一样。右侧是 ModelVisual3D,它似乎以不同方式解释 TextureCoordinates

enter image description here

这是怎么回事?由于我正在使用的软件的其他要求,我无法使用 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/

相关文章:

c# - 将命令与 TabItem 一起使用

c# - WPF Canvas 中的网格线

c# - 具有有效选择的可编辑组合框

c# - 将 UserControl 转换为自定义控件

c# - 如何访问 NSMutableArray 索引 Xamarin.ios

c# - 获取程序集而不实例化它们

.net - Azure 无法在 Windows Server 2012 辅助角色上找到证书

c# - 提取对象类型以用作通用 <T>

c# - 使用 NTLM Negotiate 时,.NET HttpClient 不会在对 IIS 的请求之间保留身份验证

c# - 用于反编译代码的 Visual Studio 或 Resharper 扩展