整理自这两篇博文

https://blog.csdn.net/u013477973/article/details/80607989?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

https://www.jianshu.com/p/0341f0ab9020

RenderType

在Unity Shader中会经常在SubShader中使用Tags,其中就会涉及RenderType和Queue,如:

SubShader{
    Tags{"RenderType"="Opaque"  "Queue"="Geometry"}
    ...
}     
RenderType
RenderType通常使用的值包括:

Opaque: 用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。
Transparent:用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。
TransparentCutout: 蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。
Background: Skybox shaders. 天空盒着色器。
Overlay: GUITexture, Halo, Flare shaders. 光晕着色器、闪光着色器。
TreeOpaque: terrain engine tree bark. 地形引擎中的树皮。
TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的树叶。
TreeBillboard: terrain engine billboarded trees. 地形引擎中的广告牌树。
Grass: terrain engine grass. 地形引擎中的草。
GrassBillboard: terrain engine billboarded grass. 地形引擎何中的广告牌草。
这些RenderType的类型名称实际上是一种约定,用来区别这个Shader要渲染的对象,当然你也可以改成自定义的名称,只不过需要自己区别场景中不同渲染对象使用的Shader的RenderType的类型名称不同,也就是说RenderType类型名称使用自定义的名称并不会对该Shader的使用和着色效果产生影响。

指定RenderType的名称,主要是为了配合使用替代渲染的方法:

Camera.SetReplacementShader("shader","RenderType")  
在使用替代渲染方法时,相机会使用指定的 shader 来代替场景中的其他 shader 对场景进行渲染。比如现在有 shader1:

Shader "shader1"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Opaque"}
    Pass{...}   
    }
    SubShader{
    Tags{"RenderType"="Transparent"}
    Pass{...}   
    }
}
场景中一部分物体当前使用的是 shader2:

Shader "shader2"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Opaque"}
    Pass{...}   
    }
}
另一部分使用的是 shader3:

Shader "shader3"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Transparent"}
    Pass{...}   
    }
}
调用替代渲染的方法:

Camera.SetReplacementShader("shader1","")   
这种情况下,场景中所有的物体就都使用shader1进行渲染(当Shader中包含多个SubShader,在渲染时显卡根据性能从上到下选择第一个能支持的shader) 
如果在调用时,第二个参数不为空字符串,即:

Camera.SetReplacementShader("shader1","RenderType")   
这种情况下,首先在场景中找到标签中包含该字符串(这里为"RenderType")的shader,再去看标签中的该字符串的值与shader1中包含该字符串的值是否一致,一致的话,替换渲染,否则不渲染;由于shader2中包含"RenderType"="Opaque",而且shader1中的第一个SubShader中包含"RenderType"="Opaque",因此将shader1中的第一个SubShader替换场景中的所有shader2,同理,将shader1中的第二个SubShader替换场景中的所有的shader3。

如果shader1为:

Shader "shader1"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Opaque" "A"="On"}
    Pass{...}   
    }
    SubShader{
    Tags{"RenderType"="Transparent"  "A"="Off"}
    Pass{...}   
    }
}   
shader2为:

Shader "shader2"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Opaque" "A"="On"}
    Pass{...}   
    }
}  
shader3为:

Shader "shader3"{
    Properties{...}
    SubShader{
    Tags{"RenderType"="Transparent" "A"="On"}
    Pass{...}   
    }
}      
替代渲染的调用方式为:

Camera.SetReplacementShader("shader1","A")      
最后的结果是,shader1的第一个SubShader将会替换shader2和shader3

渲染顺序和RenderQueue

Unity中的渲染顺序自上而下大致分为三层。 最高层为Camera层,可以在Camera的depth那里设置,设置之后,图形的渲染顺序就是先绘制depth低的相机下的物体,再绘制depth高的相机下的物体,也就是说,depth高的相机会覆盖depth低的相机(具体的覆盖关系有don't clear, solid color等等几种)

比Camera层稍低一层的是sorting layer层,随便找一个可以设置sorting layer的地方,选择sorting layer,点添加按钮,就可以看到当前所有的sorting layer,并且可以更改sorting layer的顺序,排位靠后的sorting layer会覆盖排位靠前的sorting layer。设置好sorting layer的相互关系之后,就可以给任何一个继承于Renderer类,或者有renderer的子类作为field的对象设置sorting layer了。注意这些sorting layer的遮挡关系是在同一个camera的层级下的。不同camera下的renderer渲染顺序以camera的depth为准。有的component的sorting layer可以直接在unity editor里面设置,比如Sprite Renderer。有的则需要用代码来设置,比如设置Particle system的sorting layer,就需要在代码中取到 ParticleSystem.Renderer.SortingLayer 来进行设置。

比sorting layer再低一层的是sorting order,这个数字指代的是在同一个sorting layer下的渲染顺序,用法很明显就不赘述了。

需要注意不要混淆的是gameobject的layer,和renderer的sorting layer。 gameObject的layer个人理解是一个逻辑上的分层,用于camera的culling mask等。而renderer的sorting layer则用于渲染。只有继承与renderer或者有renderer作为filed的component才需要设置sorting layer。

另外需要指出的是,常用的NGUI的widget depth其本质也是一个sorting layer下的sorting order。 NGUI好像用的是一个叫做“UI"的sorting layer。由此大家如果有需要,也可以自己取Hack NGUI的代码,把NGUI的sorting layer暴露出来供自己定制。

简单总结一下,决定Unity渲染关系的层级顺序是:
Camera
sorting layer
sortingorder

但是这些还不够,因为还没有说到比较让初学者头疼的(笔者一开始就很头疼)RenderQueue ,RenderQueue 其实就是shader中tags中的Queue

Tags { "Queue"="Geometry" }

默认情况下,Unity会基于对象距离摄像机的远近来排序你的对象。因此,当一个对象离摄像机越近,它就会优先绘制在其他更远的对象上面。对于大多数情况这是有效并合适的,但是在一些特殊情况下,你可能想要自己控制对象的绘制顺序。而使用Tags{}块我们就可以得到这样的控制。

Unity提供给我们一些默认的渲染队列,每一个对应一个唯一的值,来指导Unity绘制对象到屏幕上。这些内置的渲染队列被称为Background, Geometry, AlphaTest, GeometryLast,Transparent, Overlay。这些队列不是随便创建的,它们是为了让我们更容易地编写Shader并处理实时渲染的。

同时需在SubShader中显示声明ZWrite Off,通知Unity我们会重写物体的渲染深度排序。

Properties Value 渲染队列描述 说明
Background 1000 This render queue is rendered before any others. 这个队列通常被最先渲染(比如 天空盒)。
Geometry 2000 Opaque geometry uses this queue. 这是默认的渲染队列。它被用于绝大多数对象。不透明几何体使用该队列。
AlphaTest 2450 Alpha tested geometry uses this queue. 需要开启透明度测试的物体。Unity5以后从Geometry队列中拆出来,因为在所有不透明物体渲染完之后再渲染会比较高效。
GeometryLast 2500 Last render queue that is considered “opaque”. 所有Geometry和AlphaTest队列的物体渲染完后
Transparent 3000 This render queue is rendered after Geometry and AlphaTest, in back-to-front order. 所有Geometry和AlphaTest队列的物体渲染完后,再按照从后往前的顺序进行渲染,任何使用了透明度混合的物体都应该使用该队列(例如玻璃和粒子效果)
Overlay 4000 This render queue is meant for overlay effects. 该队列用于实现一些叠加效果,适合最后渲染的物体(如镜头光晕)。

好了,最后给出一个最终的总结:
依次按条件先后顺序进行排序渲染处理。先按大项条件排序,后按小项条件排序

1.Camera Depth: 越小越优先
2.RenderQueue 2500以下
    1. Sorting Layer/Order in Layer
           1. 按照Sorting Layer/Order in Layer 设置的值,越小越优先
           2. 无此属性,等同于 Sorting Layer=default ,Order in Layer=0 参与排序
     2.RenderQueue 越小越优先
     3.RenderQueue 相等,由近到远排序优先
3.RenderQueue 2500以上
     1. Sorting Layer/Order in Layer
           1. 按照Sorting Layer/Order in Layer 设置的值,越小越优先
           2. 无此属性,等同于 Sorting Layer=default ,Order in Layer=0 参与排序
     2.RenderQueue 越小越优先
     3.RenderQueue 相等,由远到近排序优先

说明一下:2500是关键值,它是透明跟不透明的分界点,因此我们考虑层级的时候要注意着点:renderqueue > 2500的物体绝对会在renderqueue <= 2500的物体前面,即渲染时renderqueue大的会挡住renderqueue小的,不论它的sortingLayer和sortingOrder怎么设置都是不起作用的。知道了这点,其他的就很好理解了。当两个的RenderQueue都在同一侧时,在SortingLayer高的绝对会在sortingLayer前面,无视renderqueue跟soringOrder,只有在sortingLayer相同的前提下,soringOrder高的会在sortingOrder低的前面,无视renderqueue。当sortingLayer跟sortingOrder相同时,才看renderqueue的高低,高的在前面。

UGUI中的ui默认使用的是UI/Default 材质,对应的shader中的渲染队列是Transparent

Shader "UI/Default"
{Properties{...}SubShader{Tags{"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent""PreviewType"="Plane""CanUseSpriteAtlas"="True"}...}
}

UnityShader RenderTypeQueue 渲染顺序相关推荐

  1. Unity渲染顺序文章收集

    UnityShader中的透明渲染 - 知乎 透明效果(二)-- (半)透明物体的渲染顺序_朽木zi的博客-CSDN博客_unity半透明渲染顺序

  2. U3D中物体的渲染顺序

    U3D中物体的渲染顺序 1,由SHADER中渲染队列及队列中的值决定 2,在同一队列中,若材质相同 2.1 对于UI,按其在场景层级中的先后顺序绘制 2.2 对于3D不透明物体,按其离相机的距离,由近 ...

  3. Unity 中渲染顺序的理解以及一些坑点 以及2.5D游戏中的渲染排序解决方案

    1.ZTest & ZWrite ZTest:深度测试,开启后测试结果决定片元是否被舍弃,可配置  ZWrite:深度写入,开启后决定片元的深度值是否写入深度缓冲,可配置 ZTest可设置的测 ...

  4. UGUI学习笔记之渲染顺序

    转载请注明地址:http://www.cnblogs.com/Vincentblogs/p/4083028.html QQ群:346738352 Unity技术交流群,讲纯粹的技术. 数据记录为Uni ...

  5. [html] 一个标签上同时出现三个或多个class属性,请问它的渲染顺序是怎样的?

    [html] 一个标签上同时出现三个或多个class属性,请问它的渲染顺序是怎样的? 按照css定义的顺序从前往后渲染,后定义的同类属性覆盖前面定义的. 个人简介 我是歌谣,欢迎和大家一起交流前后端知 ...

  6. 页面的加载与渲染顺序

    页面的加载与渲染顺序: 1.一个页面的加载顺序是从上到下顺序加载的,并且加载与渲染同时进行. 2.引用外部js文件时,当在加载过程中遇到标签时,浏览器会向服务器发送一个reques并等待该reques ...

  7. Unity中的物体渲染顺序

    big seven 文章目录 前言 一.摄像机渲染 二.划分渲染队列 三.不透明物体的渲染 四.透明物体的渲染 五.UGUI元素的渲染 总结 前言 Unity中物体的渲染顺序 提示:以下是本篇文章正文 ...

  8. UnityShader水墨渲染的尝试

    UnityShader水墨渲染的尝试 描边 混合纹理 先上一张原图,模型素材之类的可以在这里 下载 描边 使用最基本的dot(n,v)来计算边缘,根据需要给控制项,这里我使用了pow来使明暗对比更强烈 ...

  9. Unity 渲染顺序

    Unity中的渲染顺序自上而下大致分为三层 渲染优先级 Camera depth > Sorting Layer > Order in Layer > RenderQueue Cam ...

最新文章

  1. Matlab与线性代数--广义逆矩阵
  2. 云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core
  3. 将给定数据源生成静态HTML页面持久化到项目之外的硬盘
  4. jenkins修改pom文件_动手实践:美化 Jenkins 报告插件的用户界面
  5. linux网络编程(四)线程池
  6. 【飞秋】一起学Windows Phone7开发(十三.四 基本控件)
  7. 无法获取保存在session中的验证码
  8. 由于找不到MSVCP20.dll,无法继续执行代码
  9. 【转】C51中断函数的写法
  10. Sitecore 十大优秀功能
  11. mac配置java环境
  12. java 第一 二章作业,Java私塾跟我学系列——JAVA篇 第二章 基础语法 作业
  13. 驾驶证体检医院(114---2 挂对应的医院司机体检)
  14. HBase -ROOT-和.META.表结构(region定位原理)
  15. eclipse查看安装了哪些插件
  16. 强收红包漫天要价偷转黑车……滴滴网约车被指太任性
  17. 打造高效研发团队 (4) —— 团队文化篇
  18. 「JavaSE」-流程控制和方法
  19. 【测试】测试人员部署测试环境是什么意思
  20. 二、MacBook Pro 使用eGPU-连接eGpu篇,mac变身小台式机

热门文章

  1. 服务器t4卡在哪个位置,英特尔(Intel )X710-T4融合网络适配器4口万兆X710T4服务器网卡...
  2. mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...
  3. java中rank函数_sql rank()函数
  4. [蓝桥杯]算法提高 天天向上(记忆化搜索)
  5. [蓝桥杯][2014年第五届真题]兰顿蚂蚁(模拟)
  6. 城市规划Java_智慧城市通过边缘计算转向高层次的城市规划
  7. linux --开机自动挂载硬盘【转】
  8. php 后台运行函数,php守护进程函数 后台执行脚本的实例详解
  9. linux 后台计算,科学网-如何在Linux中做批处理和后台计算-张彦的博文
  10. python之torchlight使用_python游戏编程之pgzero使用介绍