Избежание шва в 3D модели цилиндра

У меня есть эта текстура, представляющая внутреннюю область трубы:

Я создал простую модель цилиндра (GeometryModel3D) разбив вышеупомянутую текстуру на сетку точек и затем обернув ее, чтобы сформировать цилиндр, затем отобразив на ней вышеупомянутую текстуру (каждый квадрат на сетке имеет два треугольника):

Левый и правый края текстуры встречаются на вышеуказанной черной линии шва, что нежелательно.

Я не мог использовать одну точку вершины для плавного продолжения там, потому что эта точка соответствует как 0, так и 360 градусам, что является одним углом, но двумя разными точками на краях 2D-текстуры.

Поэтому я использовал пары вершин в одном и том же месте, но каждая из которых соответствует своей точке в исходной текстуре.

Что я могу сделать, чтобы скрыть линию шва?

Код создания модели:

    private void SceneViewerWindowOnLoaded(object sender, RoutedEventArgs e)
    {
        var imageSource = new BitmapImage(new Uri("pack://application:,,,/Resources/out1.jpg"));

        var meshGeometry3D = new MeshGeometry3D();

        double circumference = imageSource.PixelWidth;
        double radius = (circumference / (2.0 * Math.PI));

        double angleSegment = (2.0 * Math.PI / SegmentCountTrans);

        double sizeSegmentLong = ((double)imageSource.PixelHeight / SegmentCountLong);
        double sizeSegmentTrans = ((double)imageSource.PixelWidth / SegmentCountTrans);

        for (int indexSegmentLong = 0; indexSegmentLong < SegmentCountLong; indexSegmentLong++)
        {
            double depth = (indexSegmentLong * sizeSegmentLong);

            for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++)
            {
                meshGeometry3D.Positions.Add(GetVertexPosition(indexSegmentTrans, depth, radius, angleSegment));
                meshGeometry3D.TextureCoordinates.Add(new Point(indexSegmentTrans * sizeSegmentTrans, depth));
            }

            // add one extra vertex representing 360 degrees for complete wrap-around
            meshGeometry3D.Positions.Add(GetVertexPosition(SegmentCountTrans, depth, radius, angleSegment));
            meshGeometry3D.TextureCoordinates.Add(new Point(SegmentCountTrans * sizeSegmentTrans, depth));
        }

        meshGeometry3D.TriangleIndices.Clear();

        for (int indexSegmentLong = 0; indexSegmentLong < (SegmentCountLong - 1); indexSegmentLong++)
        {
            for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++)
            {
                int indexCurrent = (indexSegmentLong * (SegmentCountTrans + 1) + indexSegmentTrans);

                meshGeometry3D.TriangleIndices.Add(indexCurrent);
                meshGeometry3D.TriangleIndices.Add(indexCurrent + 1);
                meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1);

                meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1);
                meshGeometry3D.TriangleIndices.Add(indexCurrent + 1);
                meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 2);
            }
        }

        var geometryModel3D = new GeometryModel3D
                            {
                                Geometry = meshGeometry3D,
                                Material = new DiffuseMaterial
                                           {
                                               Brush = new ImageBrush(imageSource)
                                           }
                            };

        this.SceneViewer.Model = geometryModel3D;
    }

    private static Point3D GetVertexPosition(int indexSegmentAngle, double depth, double radius, double angleSegment)
    {
        double angle = (StartAngle + indexSegmentAngle * angleSegment);

        return new Point3D(
            radius * Math.Cos(angle),
            radius * Math.Sin(angle),
            -depth);
    }

Код XAML для Viewport3D элемент, содержащий модель:

<Viewport3D x:Name="Viewport3D">
        <Viewport3D.Camera>
            <PerspectiveCamera x:Name="Camera" Position="0.0,0.0,0.0" LookDirection="0.0,0.0,-1.0" UpDirection="0.0,1.0,0.0" FieldOfView="90"/>
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <AmbientLight Color="White"/>
            </ModelVisual3D.Content>
        </ModelVisual3D>
        <ModelVisual3D x:Name="ModelVisualModel"/>
    </Viewport3D>

2 ответа

Решение

Когда вы создаете свою кисть изображения, попробуйте установить TileMode в TileMode.Tile и ViewportUnits в BrushMappingMode.Absolute. Если это по-прежнему не работает, то оставьте здесь дополнительный комментарий, и я постараюсь воспроизвести его с моей стороны.

Я использовал DrawingBrush вместо Imagebrush. Это исправило швы, и я также получил повышение fps при настройке кэширования.

Brush brush = new DrawingBrush(new ImageDrawing(_texture, new Rect(0,0,1,1)));
RenderOptions.SetCachingHint(brush , CachingHint.Cache);
RenderOptions.SetCacheInvalidationThresholdMinimum(brush , 0.5);
RenderOptions.SetCacheInvalidationThresholdMaximum(brush , 2.0);
Другие вопросы по тегам