ZWrite、ZTest、RenderQueueを理解する2022/04/03に公開UnityshadertechそろそろShaderをやりますそろそろShaderをやります。Shaderをやりたいからです。パート100までダラダラ頑張ります。10年かかってもいいのでやります。100記事分くらい学べば私レベルの初心者でもまあまあ理解できるかなと思っています。いう感じでやってます。2017の動画を見る(基礎知識~フラグメントシェーダーで色を変える)ZWriteデプスバッファへの書き込みについて設定できます。デプスバッファとはカメラからオブジェクトまでの距離を格納する記憶領域です。描画するピクセルと1対1で用意されています。Onにすると書き込みが有効になり、Offにすると書き込みを無効にします。デフォルトではOnになっています。この距離を深度値やZ値といい、Unityの場合0〜1で取得できます。距離が遠くなるほどに値は大きくなります。深度値がまだ書き込まれていないピクセルにおいては、初期値が書き込まれているそうです。基本的には1を設定することが多いとのことです。改訂3版Zバッファ法(デプスバッファ法)RenderQueueRenderQueueを変更することで描画順を変更できます。ここでいう"描画順"とは"レンダリングする順番"のことを指します。実際に"表示される順番"を直接的に指しているわけではないので注意が必要です。基本的には先にレンダリングされることになります。UnityのInspector上では数字で表示されますが、Shader内では既定の文字列で指定が可能です。"Geometry+1"、のようにShader内で定義します。【参考リンク】:Unityのレンダリング順についてRenderQueueの値が一致している場合、基本的にはカメラから近い順に描画されるようです。(半透明は奥から順に描画)ただ、例外もあるので厳密に描画順を制御したいならRenderQueueの値で管理した方が良さそうです。【参考リンク】:【Unity】不透明キューの描画順が手前からじゃない件ZTest描画済みのピクセルの深度値と描画予定のピクセルの深度値を比較します。ZTest以後の設定値に応じて合否(描画するかしないか)を判定します。描画のフローをイメージすると理解しやすくなります。以下の図のような空間を例に見ていきます。赤いオブジェクト、青いオブジェクト、カメラの順に配置されています。描画される順番は赤いオブジェクト、青いオブジェクトと仮定します。赤いオブジェクトが描画済みとなり、深度値が書き込まれた場面が左の図です。右の図は同じピクセルに青いオブジェクトを描画しようとしている場面です。(深度値に関してはわかりやすいように0~1に変換された後の値を例にしています)あとはこれらの深度値を比較します。この"深度値の比較によってピクセルを上書きするか定めるフロー"をZTestといいます。合格"という条件のZTestが行われた結果です。ZTestに合格したピクセルが上書きされました。ZTestの設定値は以下の通りです。深度値に関係なく合格デフォルトではLEqualとなっています。ここで注意したいのが、ZWriteをOffにしたからといって、ZTestの合格結果が一概には決定しないということです。描画予定のピクセルの深度値自体は前後関係の比較に使われています。検証ZWrite、ZTest、RenderQueueを使って検証をしてみます。Shaderサンプル以下のShaderを適用し、設定値を変えた複数のMaterialで検証します。OnとRenderQueue2000、2001の組み合わせまずはZWriteをOnにし、RenderQueueを2000にした黒いQuad、2001にした赤いQuadを並べてみます。ZTestはデフォルトのLEqualとなっています。カメラから見て遠い方に"RenderQueueが2001の赤いQuad"を配置しました。描画順はRenderQueueを2000にした黒いQuad、2001にした赤いQuadの順です。赤いQuadが描画されるタイミングで"描画予定のピクセルの深度値"との比較が行われます。不合格となったピクセルは黒いQuadを描画した時点のままとなります。OffとRenderQueue2000、2001の組み合わせ次にZWriteをOffにし、RenderQueueを2000にした黒いQuad、2001にした赤いQuadを並べてみます。ZTestはデフォルトのLEqualとなっています。こちらも先ほどと同様に、カメラから見て遠い方に"RenderQueueが2001の赤いQuad"を配置しました。描画順も先ほど同様にRenderQueueを2000にした黒いQuad、2001にした赤いQuadの順です。初期値のままとなっています。合格となったピクセルは上書きとなり、赤色で塗りつぶされます。EqualでRenderQueue2001の組み合わせ続いてはZTestについてです。EqualのRenderQueueが2001の赤いCube"を重ねて並べてみます。黒いCubeのみを非アクティブにした場合は何も描画されなくなりました。それぞれの解説は以下の通りです。双方アクティブにした場合、赤いCubeが表示された黒いCubeが描画された際にピクセルに書き込まれた深度値と"赤いCubeを描画予定となっているピクセルの深度値"が一致していたため、重なっている部分のZTestの結果は合格となり、赤いCubeが表示された。黒いCubeのみを非アクティブにした場合、何も描画されなくなった赤いCubeを描画する際に描画予定のピクセルにはまだ深度値の書き込みが行われておらず、初期値のままである。描画予定のピクセルのZ値"とならず、ZTestの結果は不合格、何も描画されなかった。Equalの使い道はいまいちわかりませんでした。GreaterにしたRenderQueueが2001の赤いCubeを並べてみます。黒いCubeの奥に赤いCubeが回り込んだ際に描画結果が変わりました。RenderQueueの関係で描画順は黒いCubeの方が先となります。赤いCubeを描画する際に行われます。Greaterの結果は不合格となります。Greaterの結果は合格となります。黒いCubeと重なっているピクセルは上書きされ、赤いCubeが描画されます。(特に明示されていない場合、記事中のソースコードはパブリックドメインです。github.com/ForJobOk/ShaderAsobiバッジを贈って著者を応援しようバッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。(特に明示されていない場合、記事中のソースコードはパブリックドメインです。Proよくある質問LinksX(Twitter)GitHubメディアキットLegal利用規約プライバシーポリシ。