庄懂技术美术入门课笔记_L13_特效类shader(AlphaBlend&AlphaCutout&Additice)
特效类shader
概述
特效特点:透、动、映射
- 序列帧动画:画成一格格,在同一张tex上
- 顶点颜色动画通常和粒子相关,粒子发射的片的显现和消失通过顶点色做变化。Shader去响应顶点色的变化。
- 应用:法阵
- 屏幕坐标加上扰动可以实现透明扭曲的效果。
各类混合方式(透切、透混、透叠)的比较
透切: AlphaCutout(AC)
-
AlphaBlend前后关系容易错乱,故复杂轮廓、明确边缘的物体常用AlphaCutout。如右图。
-
一般卡通项目会配上后处理(抗锯齿)、Bloom。Bloom会使辉光溢出来,使画面不会那么呆板。
透混:AlphaBlend (AB)
- 特效常用AlphaBlend打底,然后再用Additive提亮
透叠:Additive(AD)
- 辉光可用后处理Bloom做替代,不要过度依赖AD片
代码
透切: AlphaCutout
- RenderType可改可不改,万一用得上,最好改一下
- RenderType有很多种,默认为Opaque,为AlphaCutout准备了专门的RenderType为TransparentCutout
- 一个shader里可有多个Subshader,每个subshader声明不同的RenderType,摄像机覆盖一个Subshader。如果想要骚操作使摄像机照到的东西变成另外的样子,可以用RenderType切到另一个Subshader。
- 也可以自己写RenderType
- ForceNoShadowCasting强制关闭投影。特效一般不开投影。
特效一般会开TillingAndOffset,所以要声明_Tex_ST - 重点:Clip()函数,把参数小于0的像素丢弃,不渲染,控制透切阈值用。
Shader "AP01/L13/AC" {
Properties {
_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}
_Cutoff ("透切阈值", range(0.0, 1.0)) = 0.5
}
SubShader {
Tags {
"RenderType"="TransparentCutout" // 对应改为Cutout
"ForceNoShadowCasting"="True" // 关闭阴影投射
"IgnoreProjector"="True" // 不响应投射器
}
Pass {
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
// 输入参数
uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
uniform half _Cutoff;
// 输入结构
struct VertexInput {
float4 vertex : POSITION; // 顶点位置 总是必要
float2 uv : TEXCOORD0; // UV信息 采样贴图用
};
// 输出结构
struct VertexOutput {
float4 pos : SV_POSITION; // 顶点位置 总是必要
float2 uv : TEXCOORD0; // UV信息 采样贴图用
};
// 输入结构>>>顶点Shader>>>输出结构
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.pos = UnityObjectToClipPos( v.vertex); // 顶点位置 OS>CS
o.uv = TRANSFORM_TEX(v.uv, _MainTex); // UV信息 支持TilingOffset
return o;
}
// 输出结构>>>像素
half4 frag(VertexOutput i) : COLOR {
half4 var_MainTex = tex2D(_MainTex, i.uv); // 采样贴图 RGB颜色 A透贴
clip(var_MainTex.a - _Cutoff); // 透明剪切
return var_MainTex; // 返回值
}
ENDCG
}
}
}
透混:AlphaBlend
- 以AC为模版,AB与AC不同的是AlphaBlend不需要_Cutoff(透切阈值),并且Subshader的Tags中需要将"RenderType"=“TransparentCutout” 改为"RenderType"="Transparent”,还要加一条“Queue”=“Transparent”
- Unity渲染不透明物体:从前往后;渲染透明物体:从后往前
- 所以要在不透明的物体渲染之后渲染透明物体,AB比AC多一条“Queue”=“Transparent”
- 在Pass中声明混合方式:Blend One OneMinusSrcAlpha/Blend SrcAlpha OneMinusSrcAlpha
- Src为当前需要渲染的像素,Dst为背景像素
- Blend One OneMinusSrcAlpha边缘干净,Blend SrcAlpha OneMinusSrcAlpha边缘发黑
- 重点:别忘了在Pass中声明混合方式
- half3 finalRGB = var_MainTex.rgb;
half opacity = var_MainTex.a * _Opacity;//这两步是将var_MainTex的RGB通道和Alpha通道分离的关键步骤
Blend One OneMinusSrcAlpha与Blend SrcAlpha OneMinusSrcAlpha效果比较
Shader "AP01/L13/AB" {
Properties {
_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}
_Opacity ("透明度", range(0, 1)) = 0.5
}
SubShader {
Tags {
"Queue"="Transparent" // 调整渲染顺序
"RenderType"="Transparent" // 对应改为Cutout
"ForceNoShadowCasting"="True" // 关闭阴影投射
"IgnoreProjector"="True" // 不响应投射器
}
Pass {
Name "FORWARD"
Tags {
"LightMode"="ForwardBase"
}
Blend One OneMinusSrcAlpha // 修改混合方式One/SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
// 输入参数
uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
uniform half _Opacity;
// 输入结构
struct VertexInput {
float4 vertex : POSITION; // 顶点位置 总是必要
float2 uv : TEXCOORD0; // UV信息 采样贴图用
};
// 输出结构
struct VertexOutput {
float4 pos : SV_POSITION; // 顶点位置 总是必要
float2 uv : TEXCOORD0; // UV信息 采样贴图用
};
// 输入结构>>>顶点Shader>>>输出结构
VertexOutput vert (VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.pos = UnityObjectToClipPos( v.vertex); // 顶点位置 OS>CS
o.uv = TRANSFORM_TEX(v.uv, _MainTex); // UV信息 支持TilingOffset
return o;
}
// 输出结构>>>像素
half4 frag(VertexOutput i) : COLOR {
half4 var_MainTex = tex2D(_MainTex, i.uv); // 采样贴图 RGB颜色 A透贴
half3 finalRGB = var_MainTex.rgb;
half opacity = var_MainTex.a * _Opacity;
return half4(finalRGB * opacity, opacity); // 返回值
}
ENDCG
}
}
}
透叠:Additive
- 以AB为模版,混合模式修改为Blend OneOne即可
- 像素shader只采样RGB,Alpha就用1。Alpha通道看项目需求要不要用RT(RenderTexture)
- 商城,要把角色渲染到卡牌上(以动态出现在UI上)。先渲染角色动画RenderTexture,再把RT贴到UI上。要关心特效是否正确写入Alpha,RT要用Alpha做透贴。需要就写。
实验截图
更多混合模式
更多混合模式
混合原理
美术自定义混合面板
- 右边的面板需要用C#写
(不封装面板)代码实现
- 核心内容1:Properties中声明混合乘子和混合算符,[Enum(枚举类型)]为下面的值追加了枚举类型,枚举值是小括号里的东西枚举类型
- 核心内容2:Pass中Blend的乘子和混合算符(op)用[ ]括起来