UnityShader入門マスターノート(7)——透明効果
透明効果
一、透明効果を実現する二つの方法
二、エンジンのよく使うレンダリング方法ステップ(一般的には物体を並べ替えてからレンダリングする)
なお、Unityは、上記の方法でレンダリングを行っても問題(たとえば、ループが重なる場合)が発生するため、レンダリング順序の問題を解決するためにキューをレンダリングする方法を提供している。
三、UnityShaderのレンダリング順序
1、レンダリングキュー
SubShaderのQueueラベルを使用して、モデルがどのレンダリングキューに属するかを決定します.Unity内部では、各レンダリングキューを表す一連の整数インデックスが使用され、インデックス番号が小さいほどレンダリングが早くなります.
名前
キューインデックス番号
説明
Background
1000
このレンダリングキューは、他のキューよりも前にレンダリングされます.通常、バックグラウンドに描画する必要があるオブジェクトをレンダリングするために使用されます.
Geometry
2000
デフォルトのレンダリングキューでは、ほとんどのオブジェクトがこのキューを使用します.不透明な物体はこのキューを使用します
AlphaTest
2450
透明度テストが必要な物体はこのキューを使用します.Unity 5では、すべての不透明なオブジェクトをレンダリングした後にレンダリングするとより効率的になるため、Geometryキューから個別に分離されます.
Transparent
3000
このキュー内のオブジェクトは、すべてのGeometryオブジェクトとAlphaTestオブジェクトがレンダリングされた後、後から順にレンダリングされます.透明度ブレンド(深さ書き込みを閉じたshaderなど)を使用したオブジェクトは、キューを使用する必要があります.
Overlay
4000
このキューは、いくつかのオーバーラップ効果を実現するために使用されます.最後にレンダリングする必要があるオブジェクトは、キューを使用する必要があります.
2、実現コード
SubShader{
Tags{ "Queue"="AlphaTest"}
Pass{
···
}
}
SubShader{
Tags{ "Queue"="Transparent"}
Pass{
···
}
}
四、透明度テスト
1、説明
透明度テストは、シェーダでclip関数を使用して行います.
2、コード
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Unlit/AlphaTest"
{
Properties{
_Color("Main Tint",Color) = (1,1,1,1)
_MainTex("Main Tex",2D) = "white"{}
_Cutoff("Alpha Cutoff",Range(0,1)) = 0.5
}
SubShader{
Tags{ "Queue"="AlphaTest" "IgnoreProject"="True" "RenderType"="TransparentCutout" }
Pass{
Tags{"LightModel"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _Cutoff;
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
struct v2f{
float4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag(v2f i):SV_TARGET{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed4 texColor = tex2D(_MainTex,i.uv);
clip(texColor.a - _Cutoff);
// Equal to
// if(texColor.a - _Cutoff < 0.0){
// discard; //
//}
fixed3 albedo = texColor.rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(worldNormal,worldLightDir));
return fixed4(ambient+diffuse,1.0);
}
ENDCG
}
}
}
五、透明度混合
1、unity提供の混合コマンド:Blend
意味
説明
Blend Off
ブレンドを閉じる
Blend SrcFactor DstFactor
ブレンドをオンにし、ブレンド係数を設定します.ソースカラー(セルで生成された色)にSrcFactorを乗算し、ターゲットカラー(すでにカラーキャッシュに存在する色)にDstFactorを乗算し、両者を加算してカラーバッファに格納します.
Blend SrcFactor DSTFactor,SrcFactorA DstFactorA
上とほぼ同じですが、透明なチャネルをブレンドするには異なる因子を使用します.
BlendOp BlendOperation
ソースカラーとターゲットカラーを単純に加算してブレンドするのではなく、BlendOpentionを使用して他の操作を行います.
注意:
2、コード(以下、深度書き込みをオフにしたため、エラーのソート)
Shader "Unlit/AlphaBlend"
{
Properties{
_Color("Main Tint",Color) = (1,1,1,1)
_MainTex("Main Tex",2D) = "white"{}
_AlphaScale("Alpha Scale",Range(0,1)) = 0.5
}
SubShader{
Tags{ "Queue"="Transparent" "IgnoreProject"="True" "RenderType"="Transparent" }
Pass{
Tags{"LightModel"="ForwardBase"}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _AlphaScale;
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
struct v2f{
float4 pos:SV_POSITION;
float3 worldNormal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
float2 uv:TEXCOORD2;
};
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag(v2f i):SV_TARGET{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed4 texColor = tex2D(_MainTex,i.uv);
fixed3 albedo = texColor.rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(worldNormal,worldLightDir));
return fixed4(ambient+diffuse,texColor.a * _AlphaScale);
}
ENDCG
}
}
}
六、深さ書き込みの半透明効果をオンにする
深度書き込みをオフにすることによるエラーのソートには、次のような解決策があります.
1、2つのPassでモデルをレンダリングする
Shader ""
{
Properties{
···
}
SubShader{
···
Pass{
ZWrite On
//ColorMask ,
//ColorMask RGB | A | 0 | R、G、B、A
//
ColorMask 0
}
Pass{
···
}
}
···
}
七、ShaderLabの混合命令
1、混合の実現方式
2、ShaderLabで混合因子を設定するコマンド
ブレンド状態を設定する場合は、ブレンド式の操作と係数の設定に相当します.
コマンド#コマンド#
説明
Blend SrcFactor DstFactor
ブレンドをオンにし、ブレンド係数を設定します.ソースカラー(セルで生成された色)にSrcFactorを乗算し、ターゲットカラー(すでにカラーキャッシュに存在する色)にDstFactorを乗算し、両者を加算してカラーバッファに格納します.
Blend SrcFactor DstFactor,SrcFactorA DstFactorA
上とほぼ同じように、透明なチャネルをブレンドするために不要な因子を使用するだけです
3、ShaderLab中の混合因子
パラメータ
説明
One
ファクタ1
Zero
ファクタ0
SrcColor
ファクタはソースカラーの値です.RGBを混合するための混合式の場合、SrcColorのRGB成分を混合因子として用いる.混合Aに用いる混合式の場合、混合因子としてSrcColorのA成分を用いる
SrcAlpha
係数がソースカラーの透明度値A(Aチャネル)
DstColor
ファクタはソースカラーの値です.RGBチャネルを混合するための混合式の場合、DstColorのRGB成分を混合因子として使用する.混合Aチャネルに使用する場合、混合因子としてDstColorのA成分が使用される.
DstAlpha
係数がターゲットカラーの透明度(Aチャネル)
OneMinusSrcColor
係数は(1-ソースカラー)です.RGBを混合するための混合式の場合、結果のRGB成分を混合因子として用いる.混合Aに用いる混合式の場合、結果としてA成分を混合因子として用いる
OneMinusSrcAlpha
係数(1-ソースカラーの透明度)
OneMinusDstColor
係数は(1-ターゲットカラー)です.RGBを混合するための混合式の場合、結果のRGB成分を混合因子として用いる.混合Aに用いる混合式の場合、結果としてA成分を混合因子として用いる
OneMinusDstAlpha
係数(1-ターゲットカラーの透明度)
4、コマンド
異なるパラメータを使用してAチャネルをブレンドしたい場合は、Blend SrcFactor DstFactorを使用します.SrcFactorA DstFactorAの例:(出力色の透明度値はソース色の透明度値です)
Blend SrcAlpha OneMinusSrcAlpha,One Zero
5、混合操作
ブレンド操作コマンド
操作
説明
Add
ブレンドしたソースカラーと目的のカラーを加算します.既定のブレンド操作.使用する混合式は、Orbg=SrcFactor*Srgb+DstFactor*DrgbOa=SrcFactorA*Sa+DstFactorA*Da
Sub
混合後のソース色から混合後の目的色を減算し、使用する混合式は、Orbg=SrcFactor*Srgb-DstFactor*DrgbOa=SrcFactorA*Sa-DstFactorA*Da
RevSub
混合後の目的色から混合後のソース色を減算し、使用する混合式は、Orbg=DstFactor*Drgb-SrcFactor*SrgbOa=DstFactorA*Da-SrcFactorA*Sa
Min
ソースカラーと目的のカラーの小さい値を使用して、成分ごとに比較します.使用した混合式は,Orgba=(min(Sr,Dr),min(Sg,Dg),min(Sb,Db),min(Sa,Da)である.
Max
ソースカラーとターゲットカラーの大きな値を使用して、成分ごとに比較します.使用した混合式は,Orgba=(max(Sr,Dr),max(Sg,Dg),max(Sb,Db),max(Sa,Da)である.
なお、MinまたはMaxブレンド操作を使用する場合、ブレンド係数は実際には機能せず、元のソース色と目的色との比較結果のみを判断します。
6、一般的な混合操作
Blend SrcAlpha OneMinusSrcAlpha // (normal),
Blend OneMinusDstColor One // (Soft Additive)
Blend DstColor Zero // (Multiply) ,
// (Darken)
BlendOp Min
Blend One One
// (Lighten)
BlendOp Max
Blend One One
Blend OneMinusDstColor One // (Screen)
Blend One OneMinusSrcColor // (Screen)
Blend One One // (Linear Dodge)
7、両面レンダリング
Cull Back | Front | Off //