在渲染阶段,引擎所做的工作是把所有场景中的对象按照一定的策略(顺序)进行渲染。最早的是画家算法,顾名思义,就是像画家画画一样,先画后面的物体,如果前面还有物体,那么就用前面的物体把物体覆盖掉,不过这种方式由于排序是针对物体来排序的,而物体之间也可能有重叠,所以效果并不好。所以目前更加常用的方式是z-buffer算法,类似颜色缓冲区缓冲颜色,z-buffer中存储的是当前的深度信息,对于每个像素存储一个深度值,这样,我们屏幕上显示的每个像素点都会进行深度排序,就可以保证绘制的遮挡关系是正确的。而控制z-buffer就是通过ZTest,和ZWrite来进行。但是有时候需要更加精准的控制不同类型的对象的渲染顺序,所以就有了渲染队列。今天就来学习一下渲染队列,ZTest,ZWrite的基本使用以及分析一下Unity为了Early-Z所做的一些优化。

Unity中的几种渲染队列

首先看一下Unity中的几种内置的渲染队列,按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。

Background(1000) 最早被渲染的物体的队列。

Geometry (2000) 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列。

AlphaTest (2450) 有透明通道,需要进行Alpha Test的物体的队列,比在Geomerty中更有效。

Transparent(3000) 半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染。

Overlay (4000) 最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的。

Unity中设置渲染队列也很简单,我们不需要手动创建,也不需要写任何脚本,只需要在shader中增加一个Tag就可以了,当然,如果不加,那么就是默认的渲染队列Geometry。比如我们需要我们的物体在Transparent这个渲染队列中进行渲染的话,就可以这样写:

[csharp] view plain copyTags { "Queue" = "Transparent"}

我们可以直接在shader的Inspector面板上看到shader的渲染队列:

另外,我们在写shader的时候还经常有个Tag叫RenderType,不过这个没有Render Queue那么常用,这里顺便记录一下:

Opaque: 用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。

Transparent:用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。

TransparentCutout: 蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。

Background: 天空盒着色器。

Overlay: GUITexture,镜头光晕,屏幕闪光等效果使用的着色器。

TreeOpaque: 地形引擎中的树皮。

TreeTransparentCutout: 地形引擎中的树叶。

TreeBillboard: 地形引擎中的广告牌树

Grass: 地形引擎中的草。

GrassBillboard: 地形引擎何中的广告牌草。

相同渲染队列中不透明物体的渲染顺序

拿出Unity,创建三个立方体,都使用默认的bump diffuse shader(渲染队列相同),分别给三个不同的材质(相同材质的小顶点数的物体引擎会动态合批),用Unity5带的Frame Debug工具查看一下Draw Call。(Unity5真是好用得多了,如果用4的话,还得用NSight之类的抓帧)

可以看出,Unity中对于不透明的物体,是采用了从前到后的渲染顺序进行渲染的,这样,不透明物体在进行完vertex阶段,进行Z Test,然后就可以得到该物体最终是否在屏幕上可见了,如果前面渲染完的物体已经写好了深度,深度测试失败,那么后面渲染的物体就直接不会再去进行fragment阶段。(不过这里需要把三个物体之间的距离稍微拉开一些,本人在测试时发现,如果距离特别近,就会出现渲染次序比较乱的情况,因为我们不知道Unity内部具体排序时是按照什么标准来判定的哪个物体离摄像机更近,这里我也就不妄加猜测了)

相同渲染队列中半透明物体的渲染顺序

透明物体的渲染一直是图形学方面比较蛋疼的地方,对于透明物体的渲染,就不能像渲染不透明物体那样多快好省了,因为透明物体不会写深度,也就是说透明物体之间的穿插关系是没有办法判断的,所以半透明的物体在渲染的时候一般都是采用从后向前的方法进行渲染,由于透明物体多了,透明物体不写深度,那么透明物体之间就没有所谓的可以通过深度测试来剔除的优化,每个透明物体都会走像素阶段的渲染,会造成大量的Over Draw。这也就是粒子特效特别耗费性能的原因。

我们实验一下Unity中渲染半透明物体的顺序,还是上面的三个立方体,我们把材质的shader统一换成粒子最常用的Particle/Additive类型的shader,再用Frame Debug工具查看一下渲染的顺序:

半透明的物体渲染的顺序是从后到前,不过由于半透相关的内容比较复杂,就先不在这篇文章中说了,打算另起一篇。

自定义渲染队列

Unity支持我们自定义渲染队列,比如我们需要保证某种类型的对象需要在其他类型的对象渲染之后再渲染,就可以通过自定义渲染队列进行渲染。而且超级方便,我们只需要在写shader的时候修改一下渲染队列中的Tag即可。比如我们希望我们的物体要在所有默认的不透明物体渲染完之后渲染,那么我们就可以使用Tag{“Queue” = “Geometry+1”}就可以让使用了这个shader的物体在这个队列中进行渲染。

还是上面的三个立方体,这次我们分别给三个不同的shader,并且渲染队列不同,通过上面的实验我们知道,默认情况下,不透明物体都是在Geometry这个队列中进行渲染的,那么不透明的三个物体就会按照cube1,cube2,cube3进行渲染。这次我们希望将渲染的顺序反过来,那么我们就可以让cube1的渲染队列最大,cube3的渲染队列最小。贴出其中一个的shader:

[csharp] view plain copyShader "Custom/RenderQueue1" {

SubShader

{

Tags { "RenderType"="Opaque" "Queue" = "Geometry+1"}

Pass

{

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct v2f

{

float4 pos : SV_POSITION;

};

v2f vert(appdata_base v)

{

v2f o;

o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

return o;

}

fixed4 frag(v2f i) : SV_Target

{

return fixed4(0,0,1,1);

}

ENDCG

}

}

//FallBack "Diffuse"

}

Unity中的几种渲染队列相关推荐

  1. Unity中的四种基本光源

    Unity中的四种基本光源:点光源.方向光.聚光灯.面光灯 1.点光源 从光源位置向所有方向发射出强度相等的光线 在传输过程中不断的衰减.当传输距离达到预设的极限距离range时,光线强度衰减为0 适 ...

  2. 在Unity中制作4种不同的游戏

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:8.6 GB 含课程素材 |时长:15h ...

  3. 【Unity Shaders】Transparency —— 使用渲染队列进行深度排序

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  4. Unity中的灯光和渲染

    一:Unity中的灯光 --Directional Light:模拟太阳光.它与位置无关,是平行光,可以调整旋转角度模拟昼夜 --Spot Light:模拟车灯.手电筒的光.舞台灯光 --Point ...

  5. Unity中的三种资源加载和卸载

    前言 内容转载自: https://www.cnblogs.com/zhoujiangyue/articles/7066070.html. Unity中三种资源加载方式: 1.静态引用.具体操作:创建 ...

  6. Unity中的仿真丝袜渲染

    物理层面的分析 在开始编写Shader前,首先我们需要对丝袜这种物品在现实中的物理性质进行一个具体的分析. 丝袜有着众多的款式,形状.功能.材料各有不同,依据我在百度百科和各类淘宝爆款中丰富的调研,最 ...

  7. unity中的四种灯光

    灯光Light 一.简介 光源 (Lights) 是每个场景的重要组成部分.网格和纹理决定了场景的形状和外观,而光源则决定了三维环境的颜色和氛围.您可能会在每个场景中使用多个光源.让它们一起工作需要一 ...

  8. Unity中的第一种签到方式的源码?

    视频地址 源码: /* *┌────────────────────────────────┐ *│ 描 述: *│ 类 名:SignInSystem.cs *│ 创 建 人: *└───────── ...

  9. 第16章 Unity中的渲染优化技术

    程序优化的第一条准则: 不要优化.程序优化的第二条准则(仅针对专家! 〉: 不要优化. 一一Michael A. Jackson 在进行程序优化的时候,人们经常会引用英国的计算机科学家Michael ...

最新文章

  1. 马云口中的“计划经济”其实是一种大数据和人工智能
  2. K/3Cloud 分页报表示例参考
  3. Java中实现获取数组中最大值
  4. Windsock套接字I/O模型学习 --- 第二章
  5. 技术分享|前端性能 关键性能指标以及测量工具介绍
  6. [转载] C++灵魂所在之---多态的前世与今生
  7. loadrunner录制事件为0_利用LoadRunner编写Socket性能测试脚本简述
  8. 怎么比较字符串java_如何在Java中比较字符串?
  9. 章节3.4----队列的实现与应用
  10. 人工智能产生式系统实验—动物识别系统(txt文件导入数据库)python代码实现以及关系图
  11. 手机qq下载文件地址
  12. 搜索推荐评价指标Precision@k、Recall@k、F1@k、NDCG@k
  13. 雪球python爬虫炒股_如何使用 Python 抓取雪球网页?
  14. X/Y/Z Modem、Kermit区别
  15. C++ if条件语句用法
  16. AWD平台搭建与使用入门
  17. jQuery参考手册
  18. 致远互联巡展走进华东,共享“协同五环”价值盛宴!
  19. 记录在Vue项目里面使用腾讯地图
  20. 集合的打印、列表List、迭代器Iterators

热门文章

  1. 改善高级定制时装状况探讨
  2. Linux常用命令(面试题)
  3. c++使用opencv截取照片并判断像素值
  4. ROS时间概念总结:ros::Time、ros::Duration、定时器ros::Timerros::Rate
  5. VS2017-快捷键使用大全
  6. 你是否了解APP耗电问题?深入探索 Android 电量优化,醍醐灌顶
  7. 角度计算器 v1.0绿色免费版
  8. uniapp封装require
  9. 仿余额宝跳转精度问题
  10. STM32 DUF 模式 下载程序