[Unity] Standard.shaderを改良して裏面描画
UnityのStandard.shaderを改良する機会があったのでメモ
Unityのマテリアルは、デフォルトでStandard.shaderというUnity本体のビルトインシェーダーが設定されます。
このシェーダーは汎用的な事が色々できて便利なのですが、裏面が描画されません。
このようにCubeのようなオブジェクトに対して、VRで中を覗き込まれたりすると透けて見えてしまいます。
今回はこのStandard.shaderを改良して、裏面描画する方法を解説します。
[環境] Unity 2017.4.28f1
Standard.shaderの入手
まずは改良元のStandard Shaderを入手します。
こちらのダウンロードから好きなバージョンのビルトインシェーダーを入手可能です。
buildin_shaders-2017.4.18f.1/DefaultResourcesExtra/Standard.shader が改良元となるシェーダーです。
単純に裏面描画してみる
単純に裏面描画したい場合はCull OFFオプションを追加するだけです。
こうすると裏面は描画されたのですが、裏面もライトの影響を受けて不自然な影ができてしまいました。
これは単純にカリングをオフにしただけなので、裏面も表面と全く同じ描画がされていることが原因だと思います。
ライトの影響を受けないよう裏面を描画する
今回は裏面はライトの影響を受けないテクスチャの描画をしたかったので、もう少し改良を加えました。
まず先ほどのCull OFFオプションはパフォーマンス負荷が上がるのでもとに戻します。
裏面描画用に以下のPassを記述します。
Pass
{
Cull Front // 裏面のみ描画
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
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 = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float brightness = 0.1; // 裏面の明るさ
return tex2D(_MainTex, i.uv) * brightness;
}
ENDCG
}
このシェーダーは単純に裏面だけに明るさを固定したテクスチャを表示するもので、このPassをBase forward passとAdditive forward passの間に追加します。
こうすることで無事にライトの影響を受けずに裏面の描画ができました!
brightnessの値を変更することで裏面の明るさを変えることも可能です。
(ちなみに自己流の方法なので、もっと良い裏面描画の方法知ってる人が居たら教えて欲しいです。)