2021-09-01

Unity_UGUI|通向UGUI源码的入口VertexHelper

riki_tree关注

12019.05.23 20:32:27字数 1,534阅读 4,465

为什么要介绍VertexHelper(顶点帮助器)这个类。他在UGUI中起到了至关重要的地位。当然不了解这个类,对于使用UGUI没有任何影响。他只是看懂UGUI源码的一个基础。不看点源码,怎敢说自己精通。

前言

UGUI是图形学渲染和射线检测这两个技术结合的典型例子。图形学渲染来处理UI的显示,射线用来交互。

今天我们主要看看UI的渲染。

首先介绍一点图形学的基础知识:

1、所有的渲染对象都是由网格(Mesh)构成,Mesh的绘制单位是图元(点、线、三角形)。意思也就是说所有的游戏对象都是在绘制一些点、线、三角形的集合。

具体是如何一步一步显示到屏幕上的,可以看之前的一篇博文(实时渲染(第四版)_第2章|图形渲染管线总结):https://www.jianshu.com/p/2d8eeec9d0ef

2、顶点数据中最主要的是位置,颜色,纹理坐标,法线等。也就是说顶点中保存着其位置、颜色、纹理坐标、法线信息等。

3、贴纹理是指,将一张纹理(可以称为图片),根据纹理坐标,贴在模型上面。就好比同一个模型人,穿上了不同的衣服。纹理坐标指的是根据坐标将图片信息覆盖在Mesh表面,就相当于,柚子就贴在手腕处,裤子就贴在腿上。

正文

UGUI提供了我们自己构建顶点、三角形的类,那就是VertexHelper类。通过这个类,我们可以创建顶点,构成三角形,填充到一张mesh上,然后用MeshRenderer渲染到屏幕上,实际上我们可以直接操作Mesh类添加顶点、三角形等操作,这里的vertexHelper只是UGUI与Mesh之间的一座桥梁。

实践

接下来 我们尝试用这种办法在空物体上画出一张image图片。

首先在Unity中添加一个空对象,命名Image,Image对象需要添加MeshFilter组件,用来添加Mesh,还需要添加MeshRenderer组件,用来渲染Mesh,使其能够在屏幕中显示。

创建CreateImage.cs脚本,并挂载在Image上。

在脚本中添加Create函数,并有vertexHelper构造4个顶点(矩形):

VertexHelper vp=newVertexHelper();vp.Clear();//这里采用的添加顶点函数,函数参数分别对应了顶点位置,顶点颜色,纹理坐标vp.AddVert(newVector3(0,0,0),Color.red,newVector2(0,0));vp.AddVert(newVector3(0,1,0),Color.green,newVector2(0,1));vp.AddVert(newVector3(1,1,0),Color.blue,newVector2(1,1));vp.AddVert(newVector3(1,0,0),Color.cyan,newVector2(1,0));

接下来,我们用4个顶点构造出矩形的两个三角形:

vp.AddTriangle(0,1,2);vp.AddTriangle(2,3,0);

我们知道矩形最少是由两个三角形构成的,当然我们可以构造更多的三角形去显示一个矩形,但是这样不仅显得多余,而且对于计算机来说计算量就会上升。同时我们要注意:

Unity默认是只渲染物体的正面,背面是不渲染的。这里就涉及到构造三角形的顺序。在Unity中以顺时针方向构造三角形,这个三角形就是正面,就被会参与渲染的计算,逆时针就是背面,最终不会显示到屏幕上。

如何看三角形是顺时针还是逆时针呢。从构造三角形的三个顶点顺序(A、B、C),第一个顶点A为基准,然后指向第二个顶点B划线AB,这根线沿着第二个顶点B到第三个顶点C的连线BC扫描,扫描的方向是顺时针即为正面,逆时针即为背面(当然这个规定只是Unity的规定,其他地方要看所用的图形接口是如何规定的)。

接下来,我们填充到一张Mesh上,并将这个Mesh赋值为空物体Image的MeshFilter上。

meshFilter=this.GetComponent();Mesh mesh=newMesh();vp.FillMesh(mesh);meshFilter.mesh=mesh;

然后我们运行游戏:

vp1.gif

可以看到有一个紫色的方块从无到有。可能有小伙伴就有疑问了,创建的顶点不是紫色的啊,这是因为MeshRender渲染时候无材质的默认颜色。在来看看官方的解释:

vertexcolor.png

意思就是大部分的shder都不会显示顶点颜色,用一个可以显示顶点颜色的shader比如, partice shader去观察顶点颜色。

这时候随便用partice下的shader创建一张材质,赋给meshrender,再运行一遍就可以看到顶点颜色了。

mat.png

顶点效果就出来了:

vp2.gif

4个顶点的颜色是已知的,中间的颜色是插值得到的。具体原理还是在上文链接中有详细介绍。

当然我们也可以用Material中的颜色或者一张图片,给mesh贴上纹理,就相当于给Mesh穿上纯色或者有图案的衣服。全部代码如下:

privateMeshFilter meshFilter;privateMeshRenderer render;publicTexture tex;voidStart(){meshFilter=this.GetComponent();render=this.GetComponent();CreateAImage();}voidCreateAImage(){VertexHelper vp=newVertexHelper();vp.Clear();//这里采用的添加顶点函数,函数参数分别对应了顶点位置,顶点颜色,纹理坐标vp.AddVert(newVector3(0,0,0),Color.red,newVector2(0,0));vp.AddVert(newVector3(0,1,0),Color.green,newVector2(0,1));vp.AddVert(newVector3(1,1,0),Color.blue,newVector2(1,1));vp.AddVert(newVector3(1,0,0),Color.cyan,newVector2(1,0));vp.AddTriangle(0,1,2);vp.AddTriangle(2,3,0);Mesh mesh=newMesh();vp.FillMesh(mesh);meshFilter.mesh=mesh;//设置颜色或者纹理(这里的设置会覆盖Mesh的颜色)//想象你穿衣服是不是就把你的肤色盖着了//render.material.color = Color.red;render.material.mainTexture=tex;}

最终效果:

vp3.gif

举一反三:

想象一下圆,他同样是有三角形来构成的,我们可以用10个三角形构成一个圆,也可以用1000个三角形构成。下面我们看看三角形数量有什么差别。

直接上主要代码:

voidCreateCircle(){VertexHelper toFill=newVertexHelper();toFill.Clear();//首先添加圆心toFill.AddVert(newVector3(0,0,0),Color.white,newVector2(0.5f,0.5f));//计算单位三角形的角度floattheta=2*Mathf.PI/triCount;for(inti=0;i

看看效果:

10.png

1000.jpg

上面分别是10面和1000面的效果。

实际上36个三角形已经可以构造出很圆的圆形了。大量的三角形渲染会增加GPU负担。这也是在游戏开发中,美术为什么要限制模型的顶点与三角形数量的原因。

我们还可以搞点不一样的。想想下面是如何实现的。

vp5.gif

小结

知识点:了解VertexHelper的用法。VertexHelper有助于我们理解UGUI源码。而且我们熟悉了VertexHelper的用法后,甚至可以随心所欲的制作出独特的UI。

19人点赞

Unity

你可能感兴趣的:(2021-09-01)