本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。

这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。

========================================== 分割线 ==========================================

写在前面

为了让我们真正明白透明度,我们需要了解一下深度排序,或者说,对象的绘制顺序。Unity允许我们控制一个特定对象绘制到屏幕上的顺序,因此我们可以更好地控制哪些对象应该覆盖在其他对象上。你可以把绘制顺序理解成Photoshop中的图层的概念。在处理透明度或者类似界面对象的元素时,绘制顺序尤其重要。
本篇将会讲解如何使用Unity内置的标签(tags)来利用这个分层化的方法去渲染你的对象。这是非常重要的,因为你将会更好地控制你的对象是如何被绘制到游戏界面的。

准备工作

  1. 创建一个新的场景,以及两个球体,并且让它们排在一条线上。我们的目标是(没有蛀牙!),无论它们在3D空间中的实际坐标是什么,我们可以随你所欲地安排它们的绘制顺序,即谁在谁的上面。
  2. 为了可以看出修改绘制顺序发生的变化,我们还需要至少两个Shaders。所以,我们创建两个新的Shaders,并可以分别分别命名为Depth001和Depth002。
  3. 你的场景应该看起来和下面图片类似。

实现

Shader部分的代码实际上很简单;它仅仅需要两行新代码就可以了。
  1. 首先我们需要生命这个对象将会被绘制到那个渲染队列中。为了做到这一点,我们需要修改Tags{}块,也就是在SubShader{}的内部:
    Tags { "Queue"="Geometry-20" }
  2. 然后,我们需要告诉Unity,我们想要自己控制这个对象的渲染顺序,而不想写到深度缓存中。在上一步代码的下面添加如下代码:
    ZWrite Off
  3. 保存,返回Unity查看。你将会发现其中一个球体出现在所有对象的后面,甚至当它的3D空间中的实际坐标在所有对象前面时也是一样。如下图所示:
最后,完整代码如下:
Shader "Custom/Depth001" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "Queue"="Geometry-20" } ZWrite Off LOD 200 CGPROGRAM
#pragma surface surf Lambert sampler2D _MainTex; struct Input {
float2 uv_MainTex;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

解释

默认情况下,Unity会基于对象距离摄像机的远近来排序你的对象。因此,当一个对象离摄像机越近,它就会优先绘制在其他更远的对象上面。对于大多数情况这是有效并合适的,但是在一些特殊情况下,你可能想要自己控制对象的绘制顺序。而使用Tags{}块我们就可以得到这样的控制。
Unity提供给我们一些默认的渲染队列,每一个对应一个唯一的值,来指导Unity绘制对象到屏幕上。这些内置的渲染队列被称为Background, Geometry, AlphaTest, Transparent, Qverlay。这些队列不是随便创建的,它们是为了让我们更容易地编写Shader并处理实时渲染的。下面的表格描述了这些渲染队列的用法:
渲染队列 渲染队列描述 渲染队列值
Background 这个队列通常被最先渲染。 1000
Geometry 这是默认的渲染队列。它被用于绝大多数对象。不透明几何体使用该队列。 2000
AlphaTest 通道检查的几何体使用该队列。它和Geometry队列不同,对于在所有立体物体绘制后渲染的通道检查的对象,它更有效。 2450
Transparent 该渲染队列在Geometry和AlphaTest队列后被渲染。任何通道混合的(也就是说,那些不写入深度缓存的Shaders)对象使用该队列,例如玻璃和粒子效果。 3000
Overlay 该渲染队列是为覆盖物效果服务的。任何最后被渲染的对象使用该队列,例如镜头光晕。 4000

因此,一旦你知道你的对象属于哪一个渲染队列,你就可以指定它的内置渲染队列标签。我们的Shader使用了Geometry队列,因此我们这样写:Tags { "Queue"="Geometry" }。但是,我们希望告诉我们的对象在我们的Geometry队列中的所有对象后面、Background队列对象的前面被绘制,因此我们修改为Tags { "Queue"="Geometry-20" }。这样就告诉Unity,我们想要把这个对象当成一个立体物体,但是请在所有其他不透明对象后面渲染。
注意:Geometry对应的队列值是2000,所以"Geometry-20"意味着使用队列值为1980的队列,而数值越小意味着越先被渲染,也就会被后面渲染的对象遮挡。
最后,我们还要在SubShader块中声明ZWrite标签。这告诉Unity,我们想要重写对象的深度排序,并且我们将会为它指定一个新的渲染队列。因此,我们就简单的把ZWrite值设为Off。(不设就没有效果)

【Unity Shaders】Transparency —— 使用渲染队列进行深度排序的更多相关文章

  1. Unity3D ShaderLab 修改渲染队列进行深度排序

    Unity3D ShaderLab 修改渲染队列进行深度排序 为了更深刻的理解透明度,我们还需要学习一下深度排序,简单来说就是物体被渲染的先后顺序. Unity允许我们通过代码来控制某个特定物体渲染到 ...

  2. 关于Unity中LOD和渲染队列----渲染通道通用指令(一)

    每个shader里面有很多的subshader,如果所以的subshader都不执行的话就,就执行fallback.每个subshader都可以设置一个LOD,整个shader也有一个LOD. 系统就 ...

  3. 【Unity Shaders】Transparency —— 使用alpha通道创建透明效果

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

  4. 【Unity Shaders】Transparency —— 透明的cutoff shader

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

  5. 【Unity Shaders】Alpha Test和Alpha Blending

    写在前面 关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到半透明问题的时候,总是不知道为什么A就遮挡了B,而B明明在A前面.这篇文章就总结一下我现在的认识~ Alpha Test和A ...

  6. (转)【Unity Shaders】Alpha Test和Alpha Blending

    转自:http://blog.csdn.net/candycat1992/article/details/41599167 写在前面 关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到 ...

  7. Unity Shaders 第一个默认程序分析

    Unity Shaders 第一个默认程序 Shader "Custom/Shader" { Properties { _MainTex ("Base (RGB)&quo ...

  8. 【Unity Shaders】使用Unity Render Textures实现画面特效——建立画面特效脚本系统

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

  9. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

随机推荐

  1. curl_multi实现并发

    普通请求 curl_normal.php <?php $srart_time = microtime(TRUE); $chArr=[]; //创建多个cURL资源 for($i=0; $i< ...

  2. 学生管理系统(SSM简易版)总结

    之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...

  3. 美团、java后台实习、面经

    3月27号投了美团java后台,29号收到面试邀请,好像是金融服务平台(提交简历的时候,我当时没注意随便填的···) 一面: 介绍项目经历 根据简历问一些问题:比如我简历上有区块链相关,会要求介绍一下 ...

  4. Python小代码_13_生成两个参数的最小公倍数和最大公因数

    def demo(m, n): if m > n: m, n = n, m p = m * n while m != 0: r = n % m n = m m = r return (int(p ...

  5. 对闭包的理解(closure)

    什么是闭包: 当你声明一个局部变量时,这个局部变量有作用域,通常局部变量值只存在于你定义的Block or Function中: function() { var a = 1; console.log ...

  6. Java程序员的现代RPC指南

    Java程序员的现代RPC指南 1.前言 1.1 RPC框架简介 最早接触RPC还是初学Java时,直接用Socket API传东西好麻烦.于是发现了JDK直接支持的RMI,然后就用得不亦乐乎,各种大 ...

  7. [多线程] 生产者消费者模型的BOOST实现

    说明 如果 使用过程中有BUG 一定要告诉我:在下面留言或者给我邮件(sawpara at 126 dot com) 使用boost::thread库来实现生产者消费者模型中的缓冲区! 仓库内最多可以 ...

  8. NLP系列(3)_用朴素贝叶斯进行文本分类(下)

    作者: 龙心尘 && 寒小阳 时间:2016年2月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50629110 ...

  9. ZooKeeper之(三)工作原理

    3.1 系统架构 ZooKeeper集群是由多台机器组成的,每台机器都充当了特定的角色,各种角色在协作过程中履行自己的任务,从而对外提供稳定.可靠的服务. 由上图可知,ZooKeeper集群由多台机器 ...

  10. Python实现Mysql数据库连接池

    python连接Mysql数据库: python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接mysql数据库请求时,都是独立的去请求访问,相当浪费资源,而且访 ...