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
然后我们运行游戏:
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
最终效果:
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