【问题标题】:Avoiding seam in 3D cylinder model避免 3D 圆柱模型中的接缝
【发布时间】:2014-02-23 20:41:57
【问题描述】:

我有这个表示管道内部区域的纹理:

我创建了一个简单的圆柱体模型 (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);
    }

包含模型的 Viewport3D 元素的 XAML 代码:

<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>

【问题讨论】:

  • 我自己还没有在 WPF 中尝试过这个,但是从使用其他框架来看,这通常是纹理采样未设置为在边缘处包裹或在接缝处运行的几何边缘的结果相反的方向。您有机会发布您的圆柱体几何创建代码吗?
  • @MarkFeldman 我已经添加了代码。这是最简单的方法 - 展开的圆柱图像以 3D 形式回卷 - 问题是两个边缘的交汇点不连续。我想避免编辑原始纹理。

标签: wpf 3d textures texture-mapping uv-mapping


【解决方案1】:

当您创建图像画笔时,尝试将 TileMode 设置为 TileMode.Tile 并将 ViewportUnits 设置为 BrushMappingMode.Absolute。如果这仍然不起作用,请在此处发表后续评论,我将尝试在我的最后重现它。

【讨论】:

    【解决方案2】:

    我使用 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);
    

    【讨论】:

    • 谢谢。现在使用技巧来进一步提高性能总是好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多