我有这个纹理代表管道的内部区域:
我创建了一个简单的圆柱模型( 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>I have this texture representing internal area of a pipe:
I have created a simple cylinder model (GeometryModel3D) by dissecting the above texture to a grid of points and than wrapping this to form a cylinder, then mapping the above texture to it (each square on a grid having two triangles):
The left and right edges of the texture meet at the above black seam line, which is unwanted.
I could not use single vertex point for smooth continuation there, because that point corresponds to both 0 and 360 degrees which is single angle, but two distinct points on edges of the 2D texture.
So I have used pairs of vertices on the same location but each corresponding to different point in the source texture.
Is there anything I can do to hide the seam line?
Model creation code:
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 code for the Viewport3D element containing the model:
<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>最满意答案
在创建图像画笔时,尝试将TileMode设置为TileMode.Tile,将ViewportUnits设置为BrushMappingMode.Absolute。 如果仍然不起作用,那么在这里发布一个后续评论,我会尝试在我的最后重现它。
When you create your image brush try setting the TileMode to TileMode.Tile and ViewportUnits to BrushMappingMode.Absolute. If that still doesn't work then post a follow-up comment here and I'll try to reproduce it on my end.
更多推荐
发布评论