Более того, я также генерирую уровни детализации фрагментов. Я включаю LOD определенного фрагмента в игре в зависимости от расстояния игрока до этого фрагмента.
Проблема в том, что у меня возникают пробелы, когда два фрагмента с разными уровнями LOD пытаются соединиться. Поэтому мне по сути нужно, чтобы каждая сетка фрагментов ниже LOD_0 имела границу, равную плотности сетки LOD_0.

Я начал писать новый код генерации сетки, и вот что у меня есть на данный момент:
Код: Выделить всё
using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Unity.Collections;
using UnityEngine;
public class MeshStitchGeneration : MonoBehaviour
{
private struct BorderData : IDisposable
{
public NativeList borderVertices;
public NativeList borderTriangles;
public static BorderData Null => default;
public BorderData(Allocator allocator)
{
borderVertices = new(allocator);
borderTriangles = new(allocator);
}
public void Dispose()
{
borderVertices.Dispose();
borderTriangles.Dispose();
}
}
[SerializeField] private Mesh lod0Mesh = null;
[SerializeField] private Mesh lowerLODMesh = null;
[SerializeField] private Material material = null;
[Button("Generate")]
private void Generate()
{
var newObj = new GameObject("Generated");
newObj.transform.SetParent(gameObject.transform);
newObj.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
var filter = newObj.AddComponent();
var renderer = newObj.AddComponent();
renderer.sharedMaterial = material;
using var borderMeshData = GetBorderMeshData();
var newStitchedMesh = AppendBorderDataToMesh(in borderMeshData);
filter.sharedMesh = newStitchedMesh;
}
private BorderData GetBorderMeshData()
{
if (lod0Mesh == null)
{
Debug.LogError("No lod0Mesh assigned!");
return BorderData.Null;
}
var bound = lod0Mesh.bounds;
if (bound.size.x != bound.size.z)
{
Debug.LogError("Requires a square mesh!");
return BorderData.Null;
}
var vertices = lod0Mesh.vertices.AsSpan();
var triangles = lod0Mesh.triangles.AsSpan();
var gridSize = Mathf.RoundToInt(Mathf.Sqrt(vertices.Length));
var vertexIncrement = bound.size.x / (gridSize - 1);
var data = new BorderData(Allocator.Persistent);
var vertexIndexMapping = new Dictionary();
for (int i = 0; i < vertices.Length; i++)
{
Vector3 vertex = vertices[i];
var ox = bound.min.x;
var oz = bound.min.z;
if (vertex.x < ox + bound.size.x - vertexIncrement
&& vertex.z < oz + bound.size.z - vertexIncrement
&& vertex.x > ox + vertexIncrement * 2
&& vertex.z > oz + vertexIncrement * 2)
{
continue;
}
vertexIndexMapping[i] = data.borderVertices.Length;
data.borderVertices.Add(vertex);
}
for (int i = 0; i < triangles.Length; i += 3)
{
int v1 = triangles[i];
int v2 = triangles[i + 1];
int v3 = triangles[i + 2];
bool isV1OnBorder = vertexIndexMapping.ContainsKey(v1);
bool isV2OnBorder = vertexIndexMapping.ContainsKey(v2);
bool isV3OnBorder = vertexIndexMapping.ContainsKey(v3);
if (isV1OnBorder || isV2OnBorder || isV3OnBorder)
{
if (isV1OnBorder) data.borderTriangles.Add(vertexIndexMapping[v1]);
if (isV2OnBorder) data.borderTriangles.Add(vertexIndexMapping[v2]);
if (isV3OnBorder) data.borderTriangles.Add(vertexIndexMapping[v3]);
}
}
return data;
}
private Mesh AppendBorderDataToMesh(in BorderData borderData)
{
if (lowerLODMesh == null)
{
Debug.LogError("No lowerLODMesh assigned!");
return null;
}
var newMesh = new Mesh();
var lowerVertices = lowerLODMesh.vertices;
var lowerTriangles = lowerLODMesh.triangles;
var combinedVertices = new List(lowerVertices.Length + borderData.borderVertices.Length);
var combinedTriangles = new List(lowerTriangles.Length + borderData.borderTriangles.Length);
combinedVertices.AddRange(lowerVertices);
foreach (var borderVertex in borderData.borderVertices)
{
combinedVertices.Add(borderVertex);
}
combinedTriangles.AddRange(lowerTriangles);
int lowerVertexCount = lowerVertices.Length;
foreach (var triangleIndex in borderData.borderTriangles)
{
combinedTriangles.Add(lowerVertexCount + triangleIndex);
}
newMesh.vertices = combinedVertices.ToArray();
newMesh.triangles = combinedTriangles.ToArray();
newMesh.RecalculateNormals(); newMesh.RecalculateBounds();
return newMesh;
}
}
В настоящее время то, что я сделал внутри функции «AppendBorderDataToMesh», просто создает новую сетку, которая содержит сетку границы и кусковая сетка. Итак, всего две сетки в одной.
Как это можно увидеть на этом изображении:

Но это не то, что мне нужно. Я хочу создать новые треугольники, которые соединят граничную сетку с кусковой сеткой, по существу образуя четырехугольники между вершинами границы и ближайшими краевыми вершинами кусковой сетки.
Итак, что-то вроде этого Я думаю:

Это довольно сложно, и я не знаю, как это сделать.
Может кто-нибудь мне помочь? Был бы очень признателен
Подробнее здесь: https://stackoverflow.com/questions/790 ... s-at-seams