透明 - saitocastel1900/UnityShader GitHub Wiki
- TagでTransparentをすることで、描画順を変更して透明なものを描画するようにしている(本来は、遠くにあるオブジェクトから描画するが、これだと透明なオブジェクトを描画するときおかしくなるため、手前のものから描画する)
Properties
{
_Color("Color",Color)=(1,1,1,1)
}
//RenderTypeはGPUに伝えるレンファリングの種類
//Queueで描画順を変える
Tags { "RenderType"="Transparent" "Queue" = "Transparent" }
//1-a値=>不透明度
Blend SrcAlpha OneMinusSrcAlpha
fixed4 _Color;
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
- だがこのままだと、裏面も描画されてしまっているので、汚く見える
- 普通は、Z値を基に奥の物から前の物を描画する。しかし、半透明を描画するとき、このままだとうまく描画されなくなってしまうため、Z値を参考にしないで不透明オブジェクトを先にした後に半透明を描画している。この時、半透明モデルはZ値に書き込まれないことで、裏側も描画されるようになってしまっている=>Z値で書き込めるようにすればOK
- 一つ目のパスの「ZWrite ON」でデプスバッファを書き込みつつ、「ColorMask 0」で描画はしないようにしている
- 二つ目のパスの「ZWrite OFF」で、すでにデプスバッファは書き込んだので、書き込まなように設定して、「Ztest LEqual」で描画済みのピクセル(ピクセルに紐づいたデプスバッファ)とこれから描画するピクセルの深度値を比較して、描画するしないを決めます。ここでは「LEqual」なので、描画済み>=描画予定なら描画するようにしています
Shader "Unlit/TransparentUnlitShader"
{
Properties
{
_Color("Color",Color)=(1,1,1,1)
}
SubShader
{
Pass
{
ZWrite ON
ColorMask 0
}
Pass
{
Tags
{
"LightMode" = "UniversalForward"
"RenderType"="Transparent"
"Queue"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
ZWrite OFF
Ztest LEqual
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
half4 _Color;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
}