用纹理填充贝塞尔曲线之间的区域
Filling area between Bezier curves with texture
我想在 Unity 中动态绘制二维路段。我知道线段的 4 个边缘点和贝塞尔曲线所需的控制点。这让我可以很容易地绘制路段的外部形状,这导致(在本例中)形成道路形状的 2 条端线和 2 条曲线。
为了绘制贝塞尔曲线,我使用了这个:https://github.com/dbrizov/NaughtyBezierCurves
外形是这样的:
目标是用一些纹理填充路段。如何创建与道路形状相同的某种平面或网格?
我的第一个想法是沿着两条曲线创建平面,也许每隔 1/100 的曲线长度,然后为它们添加纹理。但是用这种方法,我不知道如何旋转平面或如何防止空间或重叠。也许有人对这个问题有更简单的解决方案。
这就是我想要实现的:
我采用 并更改了几行使其采用两个任意样条线:
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(BezierSpline))]
public class SplineMesh : MonoBehaviour {
[Range(1, 20)]
public int sampleFrequency = 5;
BezierSpline[] splines;
Mesh mesh;
private void Awake () {
splines = GetComponents<BezierSpline>();
mesh = GetComponent<Mesh>();
}
private Vector3[] vertices;
public void GenerateMesh(){
vertices = new Vector3[(sampleFrequency + 1) * 2];
//iterate over our samples adding two vertices for each one
for(int s = 0, i = 0; s <= sampleFrequency; s++, i += 2){
float interval = s / (float)sampleFrequency;
//get point along spline, and translate to local coords from world
var point1 = transform.InverseTransformPoint(splines[0].GetPoint(interval));
var point2 = transform.InverseTransformPoint(splines[1].GetPoint(interval));
vertices[i] = point1;
vertices[i + 1] = point2;
}
GetComponent<MeshFilter>().mesh = mesh = new Mesh();
mesh.name = "Spline Mesh";
mesh.vertices = vertices;
//now figure out our triangles
int [] triangles = new int[sampleFrequency * 6];
for(int s = 0, ti = 0, vi = 0; s < sampleFrequency; s++, ti += 6, vi += 2){
//first tri
triangles[ti] = vi;
triangles[ti + 1] = vi + 3;
triangles[ti + 2] = vi + 1;
//second matching tri
triangles[ti + 3] = vi;
triangles[ti + 4] = vi + 2;
triangles[ti + 5] = vi + 3;
}
mesh.triangles = triangles;
mesh.RecalculateNormals();
Debug.Log("Generated Spline Mesh");
}
}
您需要确保渲染它的着色器没有背面剔除,即 Cull Off
。
此代码在许多情况下应该有效,但理论上可能会导致边缘自重叠。在没有任何关于样条曲线相对定位的保证的情况下,我能想到的唯一解决方法是在 sampleFrequency
循环的每一步尝试对大于或等于的每个样条曲线尝试不同的 intervals
前一对 intervals
直到找到一对可以消除(或最小化)该对将添加的重叠。
至于设置uv,你可以这样设置uv:
private Vector3[] vertices;
private Vector2[] uvs;
// ...
vertices[i] = point1;
vertices[i + 1] = point2;
uvs[i] = new Vector2(0f, sample);
uvs[i+1] = new Vector2(1f, sample);
// ...
mesh.triangles = triangles;
mesh.RecalculateNormals();
mesh.uv = uvs;
我想在 Unity 中动态绘制二维路段。我知道线段的 4 个边缘点和贝塞尔曲线所需的控制点。这让我可以很容易地绘制路段的外部形状,这导致(在本例中)形成道路形状的 2 条端线和 2 条曲线。
为了绘制贝塞尔曲线,我使用了这个:https://github.com/dbrizov/NaughtyBezierCurves
外形是这样的:
目标是用一些纹理填充路段。如何创建与道路形状相同的某种平面或网格?
我的第一个想法是沿着两条曲线创建平面,也许每隔 1/100 的曲线长度,然后为它们添加纹理。但是用这种方法,我不知道如何旋转平面或如何防止空间或重叠。也许有人对这个问题有更简单的解决方案。
这就是我想要实现的:
我采用
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(BezierSpline))]
public class SplineMesh : MonoBehaviour {
[Range(1, 20)]
public int sampleFrequency = 5;
BezierSpline[] splines;
Mesh mesh;
private void Awake () {
splines = GetComponents<BezierSpline>();
mesh = GetComponent<Mesh>();
}
private Vector3[] vertices;
public void GenerateMesh(){
vertices = new Vector3[(sampleFrequency + 1) * 2];
//iterate over our samples adding two vertices for each one
for(int s = 0, i = 0; s <= sampleFrequency; s++, i += 2){
float interval = s / (float)sampleFrequency;
//get point along spline, and translate to local coords from world
var point1 = transform.InverseTransformPoint(splines[0].GetPoint(interval));
var point2 = transform.InverseTransformPoint(splines[1].GetPoint(interval));
vertices[i] = point1;
vertices[i + 1] = point2;
}
GetComponent<MeshFilter>().mesh = mesh = new Mesh();
mesh.name = "Spline Mesh";
mesh.vertices = vertices;
//now figure out our triangles
int [] triangles = new int[sampleFrequency * 6];
for(int s = 0, ti = 0, vi = 0; s < sampleFrequency; s++, ti += 6, vi += 2){
//first tri
triangles[ti] = vi;
triangles[ti + 1] = vi + 3;
triangles[ti + 2] = vi + 1;
//second matching tri
triangles[ti + 3] = vi;
triangles[ti + 4] = vi + 2;
triangles[ti + 5] = vi + 3;
}
mesh.triangles = triangles;
mesh.RecalculateNormals();
Debug.Log("Generated Spline Mesh");
}
}
您需要确保渲染它的着色器没有背面剔除,即 Cull Off
。
此代码在许多情况下应该有效,但理论上可能会导致边缘自重叠。在没有任何关于样条曲线相对定位的保证的情况下,我能想到的唯一解决方法是在 sampleFrequency
循环的每一步尝试对大于或等于的每个样条曲线尝试不同的 intervals
前一对 intervals
直到找到一对可以消除(或最小化)该对将添加的重叠。
至于设置uv,你可以这样设置uv:
private Vector3[] vertices;
private Vector2[] uvs;
// ...
vertices[i] = point1;
vertices[i + 1] = point2;
uvs[i] = new Vector2(0f, sample);
uvs[i+1] = new Vector2(1f, sample);
// ...
mesh.triangles = triangles;
mesh.RecalculateNormals();
mesh.uv = uvs;