【UnityShader】Tagブロック #4
前回の成果
inspectorから色の変更が出来るようになった
今回やること
3Dオブジェクトの透明度を変更させます!
いよいよシェーダーっぽくなってきましたね。
今回もおもちゃラボ様を参考にします。
ソースコード
Shader "Custom/translucent" { SubShader { Tags { "Queue" = "Transparent"} LOD 200 CGPROGRAM #pragma surface surf Standard alpha:fade #pragma target 3.0 struct Input{ float2 uv_MainTex; }; void surf(Input IN, inout SurfaceOutputStandard o){ o.Albedo = fixed4(0.6f,0.7f,0.4f,1); o.Alpha = 0.6f; } ENDCG } FallBack "Diffuse" }
やっていることは単純そうで、
- ベースカラーを変更している
- アルファ値を変えている
の2つのようです。
しかし前回、前々回で書いてきたものと異なる点が他にあることにお気付きでしょうか。
// 今まで Tags { "RenderType"="Opaque" } // 今回 Tags { "Queue" = "Transparent"}
このtagブロックと
// 今まで #pragma surface surf Standard fullforwardshadows // 今回 #pragma surface surf Standard alpha:fade
#pragma宣言、この2つが今までと今回で変わっています。
なので、今回は今まで触れていなかった部分に触れていこうと思っています。
Tagブロック
Tagブロックの中に"Queue"と記述があります。
これはレンダリングの順序を指定することができるものです。
今回の場合だとTransparentを指定しているので、他のオブジェクト全てを描画してからTransparentを描画します。
Transparentってなんだ
わかるそれな
Queueタグにはすでに定義済みのものがあるので、それについて説明します。
Queue名 | 用途 | 番号 |
---|---|---|
Background | 背景 | 1000 |
Geometry | 不透明なオブジェクト | 2000(デフォルト) |
AlphaTest | アルファテストするもの | 2450 |
Transparent | アルファブレンディングするもの | 3000 |
Overlay | 最後にレンダリングするもの | 4000 |
このQueueタグに定義されているものの1つがTransparentです。
アルファブレンディングとは
専門用語を専門用語で説明するなってやつですね。
アルファブレンディングとは、コンピュータグラフィックスの描画技法の一種で、ある画像にアルファ値を掛け合わせることで半透明な画像を重ねる技法のことである。 アルファブレンディングとは何? Weblio辞書:より引用
噛み砕いて説明すると、半透明オブジェクトのことです。
話は逸れますが、アルファテストとOverlayの最後にレンダリングするものの例は、また別で説明します。
なんでTransparentを指定してんの?
Tagブロックの中に"Queue"と記述があります。
これはレンダリングの順序を指定することができるものです。
今回の場合だとTransparentを指定しているので、他のオブジェクト全てを描画してからTransparentを描画します。
と前述しました。
なぜ、そうしないといけないのかはZバッファが関係しています。
このサイト様の解説がとてもわかりやすいのですが、念の為自分の言葉でも解説しておきます。 ch.nicovideo.jp
Zバッファの仕組み
15-06-06《半透明ポリゴンの描画順問題[接触篇]》:習慣 不沈空母をつくる - ブロマガ:より引用
描画を行う際に、最初に描画されるAとピクセル毎の距離が記録されます。
A以外の部分は何も描画されていないのでそのままとなります。
次のBを描画する際にピクセル毎にZバッファに記録されているAの距離と、まだ記録されていないBとの距離を比較します。
比較した値のZバッファの方がカメラに近ければ(今回の場合はAが描画されている領域)、すでにBよりカメラに近いポリゴンが描画されていると判断して、Bの描画がスキップされます。
それと同時にBの距離がZバッファに記録されます。
これによって、描画順に関係なく、AとBとの前後関係が正確に描画されます。
描画順を変えてみる
Aから描画した場合
15-06-06《半透明ポリゴンの描画順問題[接触篇]》:習慣 不沈空母をつくる - ブロマガ:より引用
まずAがZバッファに記録されてからBが記録されます。
Bから描画した場合
まずBがZバッファに記録されてからAが記録されます。
これで何が言いたいのかというと、
両方とも不透明の場合、見た目上影響は出ません
半透明の場合どうなるん
※Aは半透明
左がBを先に描画してからA、
右がAを先に描画してからBです。
理想としている描画方法は『左』です。
なんでこうなるの?
先ほど、長々と説明したZバッファの仕組みが関係してきます。
次のBを描画する際にピクセル毎にZバッファに記録されているAの距離と、まだ記録されていないBとの距離を比較します。 比較した値のZバッファの方がカメラに近ければ(今回の場合はAが描画されている領域)、すでにBよりカメラに近いポリゴンが描画されていると判断して、Bの描画がスキップされます。
ここの部分ですね。
自分なりにまとめると、
- Aを描画する
- Bを描画しようとする
- AとBが重なっている部分があるのを確認する
- Aの方がカメラに近いのでBを描画しない
という理由から描画されないということになります。
ちなみに、
アルファマスクで完全に透明な部分はZバッファに記録されないので描画順は気にしなくて良さそうです。