使用MeshData与Job System时GetVertexData长度异常问题求助
问题根源
你调用MeshData.GetVertexData<VData>()时未指定顶点流(stream),默认只会读取stream 0的内存。而你在SetVertexBufferParams中把Position放在stream 0、Normal放在stream 1,stream 0的总字节数是5120 * 3 * 4 = 61440字节,VData结构体大小为24字节(两个float3),因此计算出的数组长度为61440 / 24 = 2560,正好是预期值的一半。
当你强制翻倍长度写入时,会越界访问stream 0内存,甚至覆盖其他区域,导致法线数据被当作位置数据解析,最终出现网格渲染异常、屏幕变黑的问题。
解决方案
根据需求,有两种正确处理方式:
方式一:使用交错顶点数据(推荐,适配多数场景)
将Position和Normal放在同一个顶点流中,让顶点数据连续存储,此时VData结构体可直接访问完整顶点信息:
// 修改MeshData顶点缓冲区设置,去掉stream参数(默认统一在stream 0) meshData.SetVertexBufferParams(numVerts, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3), new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3) );
此时MeshData.GetVertexData<VData>()会返回长度为5120的NativeArray,与预期一致,后续顶点写入逻辑无需修改。
方式二:分别访问独立顶点流
若确实需要分离顶点流(如特定性能优化场景),需分别获取每个stream的NativeArray,单独写入Position和Normal:
public void Execute() { // 明确指定stream 0,获取位置数据数组(长度5120) NativeArray<float3> positions = MeshData.GetVertexData<float3>(stream: 0); // 明确指定stream 1,获取法线数据数组(长度5120) NativeArray<float3> normals = MeshData.GetVertexData<float3>(stream: 1); NativeArray<ushort> Tris = MeshData.GetIndexData<ushort>(); for (int i = 0; i < Heights.Length; i++) { ushort t1 = (ushort)(w1 + 16); Debug.Log(positions.Length); // 现在输出5120 int height = Heights[i]; int x = i / 16; int y = i % 16; float3 up = new float3(0, 1, 0); // 写入位置到stream 0 positions[t1] = new float3(x + 1, height, y + 1); // 写入法线到stream 1 normals[t1] = up; // ... 其他索引和顶点写入逻辑 } }
这种方式需确保每个stream的写入操作对应正确属性,避免数据混淆。
额外注意事项
VData结构体的[StructLayout(LayoutKind.Sequential)]已保证布局与顶点属性顺序(先Position、再Normal)匹配,无需修改。- 完成网格数据写入后,需调用
Mesh.ApplyAndDisposeWritableMeshData将MeshDataArray应用到实际Mesh对象(你的代码遗漏了这一步,也是屏幕变黑的潜在原因):
Mesh mesh = new Mesh(); Mesh.ApplyAndDisposeWritableMeshData(meshDataArray, mesh); // 后续可将mesh赋值给Renderer组件
内容的提问来源于stack exchange,提问作者Jam
相关产品推荐
相关产品推荐

