Unity Shader 学习笔记(11) 渲染队列、透明效果
2017-11-17 16:32
627 查看
Unity Shader 学习笔记(11) 渲染队列、透明效果
参考书籍:《Unity Shader 入门精要》【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑
3D数学 学习笔记(10) 背面剔除(Clipping)、裁切(Backface Culling)、光栅化(Rasterzation)
官网API:ShaderLab: SubShader Tags
透明测试所在步骤:
渲染队列(render queue)
用SubShader的Queue标签来觉得模型归于那个渲染队列。索引号越小,越早被渲染。半透明物体的渲染顺序
常用顺序:1. 先渲染所有不透明物体,开启深度测试和深度写入。
2. 半透明物体按离摄像机距离远近排序,从后往前渲染,开启深度测试,关闭深度写入。
部分相互重叠的物体不适用,解决方法是分割网格。
A为半透明,B为不透明
正确:先渲染B,后渲染A。错误:先渲染A,后渲染B。A不写入深度缓冲,B发现深度缓冲没有东西,就会直接覆盖A的颜色。
A和B都为半透明
正确:先渲染B,后渲染A。错误:先渲染A,后渲染B。A先写入颜色缓冲,B再和A混合,结果相反,使B看起来在A前面。
透明度测试
把一个片元透明度不满足条件(小于某个阈值)的舍弃掉,否则进行深度测试、深度写入等。CG中用
clip(float x)函数进行透明度测试,如果给定任一分量为负,则舍弃当前像素的输出颜色。等价下面代码:
void clip(float4 x) { if (any(x < 0)) disacard; }
Shader "Custom/AlphaTest" { Properties { ... _Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5 // 透明测试阈值 } SubShader { // 渲染队列:透明测试;不受投影器影响;指名这个Shader提前归入TransparentCutout组(指明Shader使用了透明测试)。 Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout" } Pass { ... fixed4 frag(v2f i) : SV_TARGET { ... fixed4 texColor = tex2D(_MainTex,i.uv); // 透明测试(小于阈值就discard,丢掉片元,类似直接return)。等价下面的判断。 clip(texColor.a - _Cutoff); //if ((texColor.a - _Cutoff) < 0.0) { discard; } ... // 计算光照等。 } ... } } // 保证使用透明度测试的物体可以正确地向其他物体投射阴影。 FallBack "Transparent/Cutout/VertexLit" }
透明度混合
将当前片元的透明度与已在颜色缓冲中的颜色值进行混合。需要关闭深度写入(不影响在其背后的物体),但不关闭深度测试(在不透明物体后面时,同样会被去掉)。
Unity提供混合命令:Blend,自动打开混合模式,源颜色的混合因子SrcFactor设为SrcAlpha,目标颜色的混合因子DstFactor设为OneMinusSrcAlpha(1 - SrcAlpha),混合后的颜色:
DstColornew = SrcAlpha × SrcColor + ( 1 - SrcAlpha ) × DstColorold
Properties { ... _AlphaScale ("Alpha Scale", Range(0,1)) = 1 // 整体透明度 }
SubShader { // RenderType选择Transparent用来指名这个Shader使用了透明度混合。 Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } Pass { Tags { "LightMode"="ForwardBase" } ZWrite Off // 关闭深度写入 Blend SrcAlpha OneMinusSrcAlpha // 开启混合模式。SrcAlpha:源颜色混合因子,OneMinusSrcAlpha:已存在颜色混合因子 ... fixed4 frag(v2f i) : SV_TARGET { ... //clip(texColor.a - _Cutoff); // 没有使用透明测试。 ... // 透明通道乘于材质参数,即最后颜色乘于透明度 return fixed4(ambient + diffuse,texColor.a * _AlphaScale); } ... } }
开启深度写入的半透明效果
只使用透明度混合 和 开启深度写入与透明度混合对比:使用两个Pass:
1. 开启深度写入,但不输出颜色。
2. 进行正常的透明度混合,按照像素级别的深度顺序进行透明渲染。
在透明度混合的代码中添加一个Pass即可。
ColorMask用于射着颜色通道的写掩码(write mask),可以是RGBA或其他组合,0为不输出任何颜色。
// 新加一个Pass块,先把深度信息写入深度缓冲,剔除掉了被自身遮挡的片元。 Pass { ZWrite On ColorMask 0 // 颜色通道掩码。为0:不写入任何颜色通道,不输出任何颜色。 } // 下一个Pass和上面的透明度混合代码相同 Pass { Tags { "LightMode"="ForwardBase" } ZWrite Off Blend SrcAlpha OneMinusSrcAlpha ... }
双面渲染的透明效果
直接透明混合物体 和 双面渲染的透明物体对比:使用两个Pass:
1. 第一个Pass只渲染背面。
2. 第二个Pass只渲染正面。
SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } Pass { Tags { "LightMode"="ForwardBase" } Cull Front // 剔除正面(只渲染背面) // 透明混合代码一样 } Pass { Tags { "LightMode"="ForwardBase" } Cull Back // 剔除背面 // 同上一个Pass } }
常见混合类型
类似Photoshop的混合模式。相关文章推荐
- Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(三)
- Unity Shader 学习笔记(30) Unity中渲染优化技术
- UnityShader入门精要学习笔记(十):透明效果-上部分
- Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(二)
- Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(一)
- Unity Shader 学习笔记 (四) Pass里可用的渲染没置命令
- UnityShader入门精要学习笔记(十一):透明效果-下部分
- 【iOS学习笔记 15-11-06】简单自定义navigationcontroller push和pop动画效果
- Unity Shader入门精要学习笔记 - 第8章 透明效果
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(四)渲染状态
- Unity Shader 学习笔记 (五) 积雪效果Shader
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
- 【Cocos2d-html5游戏引擎学习笔记(11)】运动中速度效果
- Unity Shader学习笔记:透明
- iOS学习笔记--iOS 11 导航栏透明设置
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
- Unity Shader 学习笔记(31) 基于物理的渲染技术(PBS)、BRDF
- Unity Shader 学习笔记(十) 滚动效果Shader实例
- [置顶] Unity Shader入门精要学习笔记 - 第2章 渲染流水线
- web前端学习笔记---利用css+filter完成简单的图片透明效果