5

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

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

  1. 使用 aViewport2DVisual3D和 aLabel作为它的Visual。将Label' 背景设置为纹理图像。使用这种方法,一切都按预期工作。
  2. 使用 aModelVisual3D和 aGeometryModel3D作为它的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>

这里是test.jpg

在此处输入图像描述

这是最终结果。左侧是Viewport2DVisual3D,它看起来与 3ds Max 中的相同。右边是ModelVisual3D,它似乎对TextureCoordinates不同的解释。

在此处输入图像描述

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

4

1 回答 1

7

我只需要ViewportUnits设置ImageBrushto Absolute

<ImageBrush x:Key="brush" ImageSource="img/test.jpg" ViewportUnits="Absolute" />

请参阅WPF3D 团队博客中的这篇文章:

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

于 2011-08-10T19:03:59.963 回答