前言

通过对替换渲染的学习,我们了解到SubShader的用法。一个SubShader可理解为Shader中的一个渲染方案。即针对不同的渲染情况,需要编写不同的子着色器。在普通情况下,shader会从上到下,并根据以下优先级选取合适的的子着色器。第一个被选到的SubShader将会直接用于渲染,而其他则被忽略。

SubShader的标签、Pass的标签:

  1. 是否符合当前的“Unity渲染路径”
  2. 是否符合当前的Replacement Tag

到目前为止,我们已经依次爬过了Properties、Subshader等内容,那么还有些什么需要搞懂呢?没错就是Pass了。同样子着色器中的Pass也是可以有很多个,当执行子着色器内的渲染方案时,所有的Pass会被依次执行,这也意味着,Pass越多,计算复杂度则越高,性能开销也更大。比如经典的过程式渲染中的卡通效果,就是用两个Pass组成的双面渲染技术实现的。

正文

在3D环境里,我们默认只对模型的正面进行渲染。因为无论如何玩家都不会看到背面或者模型内表面的画面(正常视觉效果),当然特殊的画面要求另计。因此shader会剔除掉背面来减少运算,这是通过Cull语句实现的,而默认进行的剔除则是Cull Back

自问自答

剔除后具体减少了哪些运算?

在Vertex Shader基于网格进行了数据向量化和矩阵操作后,会经过一个像素舍弃阶段,这一阶段要做的事情包括深度测试和剔除,以此来决定哪些部分需要渲染而哪些则不需要。但请读者注意,舍弃的意思仅仅代表Fragment Shader不会调用GPU的资源来进行相关的计算,虽然GPU有并行运算的能力,但对于图像渲染来说,这种计算能力依然是非常宝贵的。因此CPU的运算并没有减少,网格信息本质上仍然存在,只不过我们看不到了而已,因为那些地方最终并没有被GPU上色。比如剔除背面则表示背面不需要上色。更多资讯请移步Unity文档:

https://docs.unity3d.com/Manual/SL-CullAndDepth.html​docs.unity3d.com

如果我们不需要Shader来进行剔除的动作,那么Cull Off关闭剔除即可。我们来看一个栗子:

Shader "Custom/DoubleTransparent" {Properties{_MainTex("Main Text", 2D) = "white" {}}SubShader{Tags { "Queue" = "Transparent" }Pass{Blend SrcAlpha OneMinusSrcAlphaCull OffZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;struct appdata{float4 vertex : POSITION;float2 uv: TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 uv: TEXCOORD1;};v2f vert(appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = v.uv;return o;}float4 frag(v2f i) : SV_Target{float4 color = tex2D(_MainTex, i.uv);return color;}ENDCG}}
}

Blend SrcAlpha OneMinusSrcAlpha已经是老战友了,它表示Transparent Blend。

接下来ZWrite Off表示这个物体的深度不写入深度缓冲,那么当其他物体在深度测试中只能用渲染通道来与其对比深度,而不能用动态深度对比渲染顺序。

后面的内容基本和第三章中的Shader保持一致,只是想将一张纹理图输出而已。但这次,因为我们关闭了剔除,因此当读者将其拖到3D平面上时,会看到两面都渲染了纹理图的结果。

11.1 得像个办法把这女人娶回家

不知道大家有没有发现,无论我从哪个角度看,香菜都在看着我呢,她是不是喜欢我啊(逃)

接下来,试着在Properties中加入一个新的纹理属性

_SecondTex("Second Text", 2D) = "white" {}

接下来修改第一个Pass的Cull语句,将其更改为Cull Back,即剔除背面。我们需要加入另一个Pass来对后面的内容进行不同的渲染。如下:

Pass
{Blend SrcAlpha OneMinusSrcAlphaCull FrontZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _SecondTex;struct appdata{float4 vertex : POSITION;float2 uv: TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 uv: TEXCOORD1;};v2f vert(appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = v.uv;return o;}float4 frag(v2f i) : SV_Target{float4 color = tex2D(_SecondTex, i.uv);return color;}ENDCG
}

在这个Pass,我们剔除了前面的内容(Cull Front),并使用第二张纹理图来渲染,使得反转平面时会看到不同的画面。

优化

多Pass渲染的其中一个缺点是性能开销大,这个我们先不管。另一个缺点是复制黏贴多,对于某些人来说代码冗余是不可接受的(比如我),那么来观察一下Shader中哪些重复的语句:

  1. Blend语句
  2. ZWrite语句
  3. appdata结构体
  4. v2F结构体
  5. vert函数

对此我们需要祭出CGINCLUDE神器。这个关键字和CGPROGRAM一样使用CGEND来表示结束范围。与CGPROGRAM用来定义shader代码不同,CGINCLUDE和ENDCG之间的代码会被插入到所有Pass中,达到一次定义,多次使用的目的。在CGINCLUDE中可以插入的shader代码有这些:

  1. 变量声明
  2. 结构体定义
  3. 函数实现

那么可以知道Blend和ZWrite语句都不能放进CGINCLUDE里面,只有3到5可以。在SubShader下新增一个CGINCLUDE区块,并将结构体与函数依次填入

CGINCLUDE
sampler2D _MainTex;
sampler2D _SecondTex;struct appdata
{float4 vertex : POSITION;float2 uv: TEXCOORD0;
};struct v2f
{float4 vertex : SV_POSITION;float2 uv: TEXCOORD1;
};v2f vert(appdata v)
{v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = v.uv;return o;
}
ENDCG

记得填入的内容在两个Pass中要删掉哦。

下一章:

俊銘:Shader从入门到跑路:阶段性自我小测2(屏幕后处理、替换渲染、双Pass渲染)​zhuanlan.zhihu.com

2d shader unity 阴影_Shader从入门到跑路(11):多Pass渲染相关推荐

  1. unity 2020 怎么写shader使其接受光照?_Shader从入门到跑路:阶段性自我小测2(屏幕后处理、替换渲染、双Pass渲染)...

    以下是一些可供读者自我检测的问题,同上次一样,笔者不会提供答案,但如果实在想不明白依然可以私信笔者问思路.经某些读者建议,每题加上了分数,供各位自检. 练习1:使用第5章讲到的屏幕后处理效果,对屏幕颜 ...

  2. 2d shader unity 阴影_Unity中实现2D光照系统

    在一些 2D 游戏中引入实时光影效果能给游戏带来非常大的视觉效果提升,亦或是利用 2D 光影实现视线遮挡机制.例如 Terraria, Starbound. 2D 光影效果需要一个动态光照系统实现, ...

  3. 2d shader unity 阴影_【Unity Shader】平面阴影(Planar Shadow)

    来介绍一种适用于移动平台的高性能实时阴影解决方案--平面阴影(Planar Shadow). 由于Unity内置的实时阴影实现方式是屏幕空间阴影贴图(Screen Space Shadow Map)非 ...

  4. 2d shader unity 阴影_UNITY崩坏3角色渲染实践

    最近二次元手游,卡通渲染都挺火的.虽然公司没开这类型项目,但是渲染来玩一下也好,原理都是一样,比较简单. 在日式卡通中,<罪恶装备>.<崩坏3>的效果都很不错,都是几年前的产品 ...

  5. Spring全家桶系列–[SpringBoot入门到跑路]

    //本文作者:cuifuan Spring全家桶----[SpringBoot入门到跑路] 对于之前的Spring框架的使用,各种配置文件XML.properties一旦出错之后错误难寻,这也是为什么 ...

  6. 【Java进阶营】Spring全家桶系列–[SpringBoot入门到跑路]

    Spring全家桶----[SpringBoot入门到跑路] 对于之前的Spring框架的使用,各种配置文件XML.properties一旦出错之后错误难寻,这也是为什么SpringBoot被推上主流 ...

  7. javascript从入门到跑路-----小文的js学习笔记(25)------运动框架----匀速运动、缓冲运动、多物体运动、链式运动

    ** javascript从入门到跑路-----小文的js学习笔记(1)---------script.alert.document.write() 和 console.log 标签 javascri ...

  8. javascript从入门到跑路-----小文的js学习笔记目录

    ** javascript从入门到跑路-----小文的js学习笔记(1)---------script.alert.document.write() 和 console.log 标签 javascri ...

  9. 反手来个K8S入门到跑路

    layout: post title: 反手来个K8S入门到跑路 category: linux date: 2019-06-09 tags: linux k8s 反手来个K8S入门到跑路 前言 放假 ...

  10. Web 3D 从入门到跑路

    大厂技术  坚持周更  精选好文 前情概要 作为在该领域小白的我,在准备该主题分享之前,我信心满满的去知乎查了下,如何学习 WebGL? 如何入手webGl以及three.js呢? - 知乎[1] 前 ...

最新文章

  1. 数据流动控制学习笔记
  2. sql Server snapshots
  3. JDBC的CRUD操作之PreparedStatement的删除操作
  4. 在Ubuntu上编译libusb
  5. 存储过程 while is null_4.2 串的存储实现(2)
  6. Linux新建用户可以在shell中切换到该用户也能登录到图形桌面
  7. 架构之旅~底层提供一个统一的GetModel()的重要性
  8. 打开文件、网页、文件夹等
  9. Finalize/Dispose资源清理模式
  10. 全国行政边界矢量数据下载
  11. 荣耀9igoogle模式_创建自己的简单iGoogle小工具
  12. 火狐浏览器的css写法,CSS样式IE浏览器跟火狐浏览器兼容写法
  13. 小记 events.EventEmitter.call
  14. can‘t connect to mysql server on localhost解决办法。 net start mysql——无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动。
  15. c语言俄罗斯方块程序设计论文,c语言俄罗斯方块游戏程序设计报告
  16. 同步压缩变变时频分析和盲源分离
  17. PS系列之 -- 通道抠图进阶 : 用通道抠取头发
  18. 如何用html5创作一个游戏
  19. 量子力学=粒子理论?量子波函数或许没有想象中那么神秘
  20. 解决Outlook不能打开的问题

热门文章

  1. Android SDK Permission大全访问权限
  2. 通过帮网友解答问题训练同学们使用awk,sed案例
  3. mysql导入存储过程报错_mysql导入存储过程时declare报错的有关问题解决
  4. 伙伴算法的核心思想是回收时进行相邻块的合并_Linux内存管理之伙伴算法
  5. C程序设计--排序(冒泡、选择、插入)--插入
  6. 美式期权损益图matlab,期权损益图的画法
  7. python模板语言_3 个 Python语言 模板库比较
  8. linux windows市场占有率,Windows 10市场份额罕见倒退:Win7也跌了 Linux暴增111%
  9. maker 预测_Nature | 计算机首次预测天然产物逆合成路线—与人类不相上下!
  10. python编程设计圆柱_《学习PYTHON—做个有编程能力的设计师》怎么样_目录_pdf在线阅读 - 课课家教育...