unity shader之——基本的渲染概念

一、逐顶点计算和逐像素计算

1.1 逐顶点计算

在vertex函数中进行的计算就叫逐顶点计算,该计算量只和模型的顶点数量或面的数量有关,而和其他因素(如模型在屏幕上的大小)无关。在unity的表面着色器中,逐像素的计算发生在vertex:vertexfunction所确定的函数中。

1.2 逐像素计算

在fragment函数中进行的计算就叫逐像素计算,这个计算量和模型的具体顶点数量以及面数无关,而和物体在屏幕上的大小有关。而3个点确定的面经过栅格化之后,往往会产生成百上千的像素,因此逐像素和逐顶点计算的计算量往往相差数个数量级。逐顶点计算和逐像素计算是着色器计算、渲染优化的重点。

1.3 如何在这两个概念中取舍

尽量把计算移动到vertex函数中,同时使逐像素计算的面在屏幕上尽量小。另外在移动平台的顶点数不要超过10的6次方。在PC上要限制在10的7次方级别内。

二、绘制调用的意义

2.1 绘制调用的概念

绘制调用是CPU为GPU准备渲染数据并令GPU进行一次渲染的操作。这是系统的一个底层操作,涉及大量的数据生成和前期准备,因此是重量级的。

2.2 正确理解绘制调用对开发应用的意义

绘制调用是一个重要指标,具体就是CPU和GPU交互、协同的一个重要指标,或者说是瓶颈。它终究只是CPU和GPU交互效率 一个指标,并不是一切。对于GPU来说,一次绘制调用的消耗还是具体看绘制调用的内容,也就是着色器的具体代码。

2.3 合批的概念和unity为优化绘制调用所做的工作

通过把数个或数百个简单的、共用同一材质的物体合并为一个网格,unity仅使用一个绘制调用就能完成渲染,而不需要数十次或数百次绘制调用。有两种类型的合批:动态的和静态的。对于静态的合批,只有当物体使用同一材质并且物体不受实时阴影影响时,动态合批才会发生。对于前向渲染路径,ForwardAdd的通道也不会被合批。对于静态合批,必须将物体标记为static类型,但是unity目前会为每一个合批的几何体创建一个几何数据的备份,这意味着需要更多的内存。因此如果应用对内存占用很敏感,可以考虑禁用静态合批。

目前unity对网格渲染器和粒子进行了合批,对于蒙皮、布料和拖尾效果并未进行合批。对于蒙皮、布料和拖尾效果未进行合批。对于半透明物体,由于需要从后往前进行渲染,因此也很难进行合批。

2.4 优化绘制调用

使用尽量少的材质,这样unity可以在合批时尽量合并物体的网格,减少Draw Call。当然也可以手动合并小物体的网格。合理地布局重要的光源,使一个物体尽量少地受逐像素渲染的光源影响。

三、利用渲染队列的技巧

3.1 渲染队列的概念

渲染队列是子着色器的标签为Queue的值,该值告诉unity使用此材质的物体的渲染优化次序。

3.2 设置渲染队列的技巧

如何利用渲染队列优化渲染?首先考虑为场景的主要角色设置一个小一点的渲染队列,这样就可以首先渲染主要角色,从而在深度测试时,遮挡掉角色后面那部分,进而减少计算。然后为那些经常被遮挡的角色和物体设置一个大的渲染队列,这样就会在靠后的时候渲染它们,这时很可能在深度测试的时候失败,从而减少了一部分计算量。最后如果有天空,把它们的渲染队列设置到最大,这样就有尽可能大的概率,在深度测试时剔除掉这些点。对于非透明的物体,一个正确的、系统的渲染队列排序,可以剔除掉很多像素点的渲染。

版权声明:本文为CSDN博主「小橙子0」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cgy56191948/article/details/103560869

推荐阅读