我正在努力在wpf中正确映射纹理。首先,3d不是我的力量,但我有一些示例代码和下面的输出图像。我正在拍摄多边形,执行三角测量,然后尝试在输出上映射矩形纹理。我得到的问题是我无法将纹理映射到平滑的跟随曲线。一个纹理贴图使用了3dtools.dll库并且效果很好,但生成的纹理贴图在左侧生成输出。它没有像我想要的那样倾斜。右边的结果图像是我尝试手动将纹理坐标映射到图像。我理解它为什么会这样,但我不确定如何纠正它?
private void simpleButtonClick(object sender, RoutedEventArgs e)
{
ClearViewport();
SetCamera();
PathGeometry FlatPath;
Geometry Geo = Geometry.Parse("M 0,0 L 0,10 C 4,4 6,6 10,10 V 0 C 6,-4 4,-6 0,0");
var GeoText = FormattedText.BuildGeometry(new Point(0, 0));
FlatPath =
Geo.GetFlattenedPathGeometry(.01,
ToleranceType.
Absolute);
var vertices = new List<Vertex>();
foreach (PathFigure Figure in FlatPath.Figures)
{
List<Point> PointList = DumpFigureToList(Figure);
vertices.AddRange(PointList.Select(p=>new Vertex((float)p.X,(float)p.Y)));
}
// Write out the data set we're actually going to triangulate
var angulator = new Triangulator();
List<Triad> triangles = angulator.Triangulation(vertices, true);
var Bounds = FlatPath.Bounds;
var mesh = new MeshGeometry3D();
var cube = new Model3DGroup();
var Count = 0;
foreach (var Tri in triangles)
{
Tri.MakeCounterClockwise(vertices);
if (FlatPath.FillContains(new Point(Tri.circumcircleX, Tri.circumcircleY)))
{
var p0 = new Point3D(vertices[Tri.a].x, vertices[Tri.a].y, 0);
var p1 = new Point3D(vertices[Tri.b].x, vertices[Tri.b].y, 0);
var p2 = new Point3D(vertices[Tri.c].x, vertices[Tri.c].y, 0);
mesh.Positions.Add(p0);
mesh.Positions.Add(p1);
mesh.Positions.Add(p2);
mesh.TriangleIndices.Add(Count);
Count++;
mesh.TriangleIndices.Add(Count);
Count++;
mesh.TriangleIndices.Add(Count);
Count++;
Vector3D normal = CalculateNormal(p0, p1, p2);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.a].x) / Bounds.Width, vertices[Tri.a].y > 0 ? 1 : 0));
mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.b].x) / Bounds.Width, vertices[Tri.b].y > 0 ? 1 : 0));
mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.c].x) / Bounds.Width, vertices[Tri.c].y > 0 ? 1 : 0));
if (wireframeCheckBox.IsChecked == true)
{
var wireframe = new ScreenSpaceLines3D();
wireframe.Points.Add(p0);
wireframe.Points.Add(p1);
wireframe.Points.Add(p2);
wireframe.Points.Add(p0);
wireframe.Color = Colors.LightBlue;
wireframe.Thickness = 2;
this.mainViewport.Children.Add(wireframe);
}
}
}
//mesh.TextureCoordinates = _3DTools.MeshUtils.GeneratePlanarTextureCoordinates(mesh, new Vector3D(0, 0, 1));
var myBrush = new ImageBrush();
myBrush.ImageSource =
new BitmapImage(new Uri(@"curvedown.png", UriKind.Absolute));
Material material = new DiffuseMaterial(myBrush);
var model = new GeometryModel3D(mesh, material);
var group = new Model3DGroup();
group.Children.Add(model);
PointLight light = new PointLight(Colors.White, new Point3D(10,10,10));
group.Children.Add(light);
var Model = new ModelVisual3D();
Model.Content = group;
this.mainViewport.Children.Add(Model);
}
以上是线框的输出。我正在使用注释掉的纹理坐标代码。在右侧手动代码(取消注释)。
答案 0 :(得分:4)
随着你的三角测量,它永远不会像你期望的那样正确地弯曲。要实现这种弯曲,您必须手动生成细条纹。像
这样的东西++++++++ |||||||| |||||||| ++++++++
- 其中每个+是一个顶点 - 但不是将其直线化,而是沿着半径的特定偏移沿着来自公共点(虚拟圆)的不同线进行映射。
在伪代码中:
for each i from 0 to nStripes let angle = start + (end-start) * i / nStripes let p1 = Point where X = innerRadius * cos(angle) Y = innerRadius * sin(angle) let p2 = Point where X = outerRadius * cos(angle) Y = outerRadius * sin(angle) add vertex at p1 add vertex at p2
然后成对地连接先前生成的边,因此(0,1)+(2,3)将生成四边形,(2,3)+(4,5)另一个,依此类推...
你必须决定哪些条纹足够好。请记住,三角形内的纹理映射总是通过线性插值完成,而不是曲线,所以你不能指望像曲线或梯形这样的东西神奇地看起来正确。