为什么TextureCoordinates按照预期运行Viewport2DVisual3D,但不适用于GeometryModel3D?

Mat*_*hew 5 .net c# 3d wpf uv-mapping

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

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

  1. 使用Viewport2DVisual3D具有Label作为Visual.将Label背景设置为纹理图像.使用此方法,一切都按预期工作.
  2. 使用ModelVisual3D具有GeometryModel3D作为Content.将GeometryModel3D材质设置为DiffuseMaterial使用图像作为其画笔的材质.使用这种方法,TextureCoordinatesMeshGeometry3D似乎是不同的解释.

完整代码如下.代码隐藏是空的,除了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>
Run Code Online (Sandbox Code Playgroud)

这是test.jpg:

在此输入图像描述

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

在此输入图像描述

这里发生了什么?由于我正在处理的软件的其他要求,我不能使用Viewport2DVisual3D.我怎样才能正确GeometryModel3D解释TextureCoordinates

Mat*_*hew 7

我不得不设置ViewportUnitsImageBrushAbsolute:

<ImageBrush x:Key="brush" ImageSource="img/test.jpg" ViewportUnits="Absolute" />
Run Code Online (Sandbox Code Playgroud)

这个职位从WPF3D团队博客:

如果未将TileBrush.ViewportUnits设置为BrushMappingMode.Absolute,则纹理坐标将相对于几何的边界框.例如,假设您只希望将v中的一半纹理映射到网格.在其他API中,您只需将坐标范围从0.0 - > 0.5.如果你在WPF3D中没有将ViewportUnits设置为Absolute,那么它仍会映射整个事物.基本上任何时候你不想要整个纹理的一个副本你想要设置绝对.