unity3d - 用纹理填充贝塞尔曲线之间的区域
问题描述
我想在 Unity 中动态绘制 2D 路段。我知道段的 4 个边缘点和贝塞尔曲线所需的控制点。这使我可以很容易地绘制路段的外部形状,这导致(在此示例中)形成道路形状的 2 条端点线和 2 条曲线。
为了绘制贝塞尔曲线,我使用这个:https ://github.com/dbrizov/NaughtyBezierCurves
目标是用一些纹理填充路段。如何创建某种具有相同道路形状的平面或网格?
我的第一个想法是沿着两条曲线走并创建平面,可能是曲线的每 1/100 长度,然后向它们添加纹理。但是使用这种方法,我不知道如何旋转平面或如何防止空间或重叠。也许有人对这个问题有更简单的解决方案。
解决方案
我从一个相关问题中获取了 Dshook 的答案并更改了几行以使其采用两个任意样条曲线:
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
直到找到一对删除(或最小化)该对将添加的重叠。
至于设置 uvs,你可以像这样设置 uvs:
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;
推荐阅读
- android - 应用程序在不使用 Asynctask 处于调试模式时崩溃
- html - IBM-WCM 插件逻辑需要显示图像,否则使用视频
- android - 我如何修复致命异常:main android.os.NetworkOnMainThreadException
- javascript - Node.js puppeteer - 从没有标签的 txt 文件中获取数据
- javascript - 通过 JS 设置时,引导输入验证消息不显示 php
- java - SpringBoot 集成测试 Sybase 和 Testcontainers
- ios - 在 iOS 中以编程方式生成 p12?
- salesforce - DocuSign 与 Drawloop 文档生成一起使用
- java - 如果我想在这种情况下减少样板代码,我应该使用继承吗?
- maven - 导入 cucumber.api.junit 无法解析