Почему текстурные координаты работают должным образом для Viewport2DVisual3D, а не для GeometryModel3D? - PullRequest
5 голосов
/ 09 августа 2011

У меня есть модель, которую я создал в 3ds Max.Модель представляет собой простой прямоугольник.Его текстура имеет перекрывающиеся текстурные координаты - модель должна отображать правую половину файла изображения дважды, бок о бок.Я экспортировал эту модель как .obj и преобразовал ее в XAML, используя Microsoft Expression Blend.

Я взял MeshGeometry3D из смеси и добавил его к Viewport3D, используя два метода:

  1. Используйте Viewport2DVisual3D с Label в качестве Visual.Установите фон Label на изображение текстуры.Используя этот метод, все работает как положено.
  2. Используйте ModelVisual3D с GeometryModel3D в качестве Content.Установите для материала GeometryModel3D значение DiffuseMaterial, которое использует изображение в качестве кисти.При использовании этого метода TextureCoordinates из MeshGeometry3D интерпретируется по-разному.

Полный код приведен ниже.Код позади, кроме 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?

1 Ответ

7 голосов
/ 10 августа 2011

Мне просто нужно было установить ViewportUnits на ImageBrush на 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, он все равно будет отображать все это. По сути, в любое время, когда вам не нужна одна копия всей текстуры, вам нужно установить Absolute.

...