在编写几何着色器的时候发现默认的plane无法满足需求,并且顶点顺序未知,于是便写了一个网格生成代码,便于生成指定大小的plane,且顶点顺序可控。
效果如下:
一个单元格由4个顶点,两个三角面组成。
四个顶点如下图
则生成面的顶点顺序为:
左上三角形:0 -> 1 -> 2
右下三角形:2 -> 3 -> 0unity中顺时针绘制为正面,逆时针绘制为反面。
实现脚本如下:
//planebuilder.cs
using system.collections;
using system.collections.generic;
using unityengine;
#region editor
#if unity_editor
using unityeditor;
[customeditor( typeof (planebuilder))]
public class planebuildereditor : editor
{
public override void oninspectorgui()
{
planebuilder builder = (planebuilder)target;
editorgui.beginchangecheck();
base .oninspectorgui();
if (editorgui.endchangecheck())
{
builder.updatemesh();
}
if (guilayout.button( "更服务器之家格" ))
{
builder.updatemesh();
}
}
}
#endif
#endregion editor
[requirecomponent( typeof (meshfilter), typeof (meshrenderer))]
public class planebuilder : monobehaviour
{
[serializefield]
private meshfilter _meshfilter;
[serializefield]
private meshrenderer _meshrenderer;
/// <summary>
/// 单元格大小
/// </summary>
[serializefield]
private vector2 _cellsize = new vector2(1, 1);
/// <summary>
/// 网格大小
/// </summary>
[serializefield]
private vector2int _gridsize = new vector2int(2, 2);
public meshrenderer meshrenderer
{
get
{
return _meshrenderer;
}
}
public meshfilter meshfilter
{
get
{
return _meshfilter;
}
}
private void awake()
{
_meshfilter = getcomponent<meshfilter>();
_meshrenderer = getcomponent<meshrenderer>();
updatemesh();
}
public void updatemesh()
{
mesh mesh = new mesh();
//计算plane大小
vector2 size;
size.x = _cellsize.x * _gridsize.x;
size.y = _cellsize.y * _gridsize.y;
//计算plane一半大小
vector2 halfsize = size / 2;
//计算顶点及uv
list<vector3> vertices = new list<vector3>();
list<vector2> uvs = new list<vector2>();
vector3 vertice = vector3.zero;
vector2 uv = vector3.zero;
for ( int y = 0; y < _gridsize.y + 1; y++)
{
vertice.z = y * _cellsize.y – halfsize.y; //计算顶点y轴
uv.y = y * _cellsize.y / size.y; //计算顶点纹理坐标v
for ( int x = 0; x < _gridsize.x + 1; x++)
{
vertice.x = x * _cellsize.x – halfsize.x; //计算顶点x轴
uv.x = x * _cellsize.x / size.x; //计算顶点纹理坐标u
vertices.add(vertice); //添加到顶点数组
uvs.add(uv); //添加到纹理坐标数组
}
}
//顶点序列
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int startindex = 0;
int [] indexs = new int [_gridsize.x * _gridsize.y * 2 * 3]; //顶点序列
for ( int y = 0; y < _gridsize.y; y++)
{
for ( int x = 0; x < _gridsize.x; x++)
{
//四边形四个顶点
a = y * (_gridsize.x + 1) + x; //0
b = (y + 1) * (_gridsize.x + 1) + x; //1
c = b + 1; //2
d = a + 1; //3
//计算在数组中的起点序号
startindex = y * _gridsize.x * 2 * 3 + x * 2 * 3;
//左上三角形
indexs[startindex] = a; //0
indexs[startindex + 1] = b; //1
indexs[startindex + 2] = c; //2
//右下三角形
indexs[startindex + 3] = c; //2
indexs[startindex + 4] = d; //3
indexs[startindex + 5] = a; //0
}
}
//
mesh.setvertices(vertices); //设置顶点
mesh.setuvs(0, uvs); //设置uv
mesh.setindices(indexs, meshtopology.triangles, 0); //设置顶点序列
mesh.recalculatenormals();
mesh.recalculatebounds();
mesh.recalculatetangents();
_meshfilter.mesh = mesh;
}
#if unity_editor
private void onvalidate()
{
if ( null == _meshfilter)
{
_meshfilter = getcomponent<meshfilter>();
}
if ( null == _meshrenderer)
{
_meshrenderer = getcomponent<meshrenderer>();
if ( null == _meshrenderer.sharedmaterial)
{
_meshrenderer.sharedmaterial = new material(shader.find( "standard" ));
}
}
}
#endif
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/u012741077/article/details/82349629
dy(“nrwz”);