本日はシェーダー学習枠です。

〇不透明なオブジェクトの描画順
描画処理が行われる際は一般的に遠くにあるものから塗りつぶされるように描画が行われています。



半透明なオブジェクトは不透明なオブジェクトの描画が完了した後に処理が実行されます。
これはRenderDocなどのデバッグツールを使用することで実際に目にすることができます。


これは不透明なオブジェクトがシェーダーによって計算されたピクセルをそのまま塗りつぶすのに対して、半透明なオブジェクトはシェーダーによって描画される際にすでに描画されているピクセル色の影響を考慮して計算結果が描画される仕組みになっているためです。
まずは上記の例でDrawTransparentObjectsに含めるようにする必要があります。
〇RenderType Transparent
RenderTypeはShaderLabのTagsブロックで記述できるシェーダーの属性です。
Tags { "RenderType"="Transparent" }
上記のように記述することでRender Queueが3000へとデフォルトで指定されるようになりDrawTransparentObjectsのイベントで処理が行われるようになります。


Render Queueは描画順番に関する値ですが、2000番は不透明オブジェクト、3000番は半透明オブジェクトのように値によって描画イベントを変える仕組みがあります。
〇AlphaBlend
RenderTypeをTransparentに変えるだけでは処理の場所が変わるだけで透明度を扱うことはできません。
透明度を扱うためにはすでに描画されたピクセルと新たにシェーダーによって計算されたピクセルをどのように合成するかという設定が必要です。
この設定をAlphaBlendと呼びます。
UnityではShaderLab内のSubShader内で*Blender 〇〇**のように定義します。
SubShader
{
Tags { "RenderType"="Transparent" }
LOD 100
Blend One One//追加
Pass
{
・・・・
}
Blendは2つの引数を使用でき、第一引数でBlend操作、第二引数でBlend係数として定義できます。
今回の場合はOneを使用しており、これはシェーダーによって計算した色をそのまま使用することを示します。
これによって半透明なシェーダーが完成します。

今回の場合One Oneのため、DrawOpaqueObjectsで計算されたピクセル色にDrawTransparentObjectsの計算結果を合成しています。
一般的なペイントソフトなどではこの処理をオーバーレイと呼びます。
〇ソースコード
Shader "Unlit/Transparent"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Transparent" }
LOD 100
Blend One One
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = TransformObjectToHClip(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
float4 frag (v2f i) : SV_Target
{
// sample the texture
float4 col = tex2D(_MainTex, i.uv);
col.a = 0.5f;
return col;
}
ENDHLSL
}
}
}