【UnityShader】テクスチャのカリング #19
前回の成果
VertexShaderとFragmentShaderを理解しました。
今回やること
テクスチャのカリングを行います。
前準備
PlaneをScene上に配置します。
今回使用した画像サイト様はこちらです。
ソースコード
2つあります。
1つ目はScriptです。
using UnityEngine; public class RotateObject : MonoBehaviour { void Update () { transform.Rotate(new Vector3(0,0,90.0f) * Time.deltaTime); } }
継続的に回転させているだけです。
カメラに移す関係で、Z軸回転をしています。
2つ目はShaderです。
Shader "Unlit/culling" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader{ Tags { "RenderType"="Transparent" "Queue"="Transparent" } LOD 200 Cull off Blend SrcAlpha OneMinusSrcAlpha Pass { 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 { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
textureを描画しているように見えます。
しかし、見慣れないソースが何点かあります。
復習
自分自身軽く抜けていた点があったので復習していこうと思います。
Tags
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
Shader側に不透明なオブジェクトと伝えます。
記述がないとこうなります。
LOD
LOD 200
しきい値のことです。
詳しくはこちらになります。
tex2D
fixed4 col = tex2D(_MainTex, i.uv);
UV座標からテクスチャのピクセルの色を返すものです。
Cull off
この1行でカリングがoffになります。
そもそもカリングとは、描画する必要がないポリゴンを描画しないようにする手法です。
例えばこのような広いマップを制作しました。
しかし、カメラに映らない部分(白い線で囲まれていない部分)は、見えないので描画する必要がありません。
なので、次の画像のように描画しないようにするものです。
今回の場合、カリングがonだと次のgifのように裏面が描画されません。
Blend SrcAlpha OneMinusSrcAlpha
ブレンディングのことです。
Blend SrcFactor DstFactor
で定義することができます。
SrcFactorはFragment Shaderでreturenされた色に乗算します。
DstFactorはShaderが処理される前にすでに画面に描画されている色に乗算します。
なので、最終的には
Fragment Shaderで計算した色 * SrcFactor + すでに画面に描画されている色 * DstDactorとなります。
Blend SrcAlpha OneMinusSrcAlpha
上記のソースコードでは、テクスチャの透明部分を透過させるようにしています。
Blend係数一覧
Sourceは計算された色のことを指します。
Destinationはすでに設定されているスクリーン上の色のことです。
係数名 | 用途 |
---|---|
One | Source、またはDestinationの色をそのまま使用したい場合 |
Zero | Source、またはDestinationの色を削除したい場合 |
SrcColor | Sourceの色を乗算 |
SrcAlpha | SourceのAlpha値を乗算 |
DstColor | フレームバッファのSourceの色を乗算 |
DstAlpha | フレームバッファのSourceのAlpha値を乗算 |
OneMinusSrcColor | フレームバッファの(1-Sourceの色)を乗算 |
OneMinusSrcAlpha | フレームバッファの(1-SourceのAlpha値)を乗算 |
OneMinusDstColor | フレームバッファの(1-Destinationの色)を乗算 |
OneMinusDstAlpha | フレームバッファの(1-DestinationのAlpha値)を乗算 |
#include "UnityCG.cginc"
cgincファイルに定義された処理が使えるようになります。
今回のソースコードにある構造体のappdataもいくつか定義されています。
struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_tan { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_full { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; fixed4 color : COLOR; };
#include "UnityCG.cginc"の中身はこちらです。
https://gist.github.com/hecomi/9580605
TRANSFORM_TEX
テクスチャのスケールとオフセットを適応するものです。
TRANSFORM_TEXを使用する際には定数として、
float4 テクスチャ名_ST
が必要です。
今回は、テクスチャ名が_MainTexなので
float4 _MainTex_ST;
を宣言します。
結果
ソースコードにコメントを付与
Shader "Unlit/culling" { // プロパティ Properties { // テクスチャ _MainTex ("Texture", 2D) = "white" {} } // Shaderの中身を記述 SubShader{ // 不透明なオブジェクト Tags { "RenderType"="Transparent" "Queue"="Transparent" } // しきい値 LOD 200 // カリングをoffに Cull off // 透過処理 Blend SrcAlpha OneMinusSrcAlpha // レンダリングの方式 Pass { // cg言語記述 CGPROGRAM // vertexShaderの宣言 #pragma vertex vert // fragmentShaderの宣言 #pragma fragment frag // インクルード #include "UnityCG.cginc" // appdata構造体 struct appdata { // pos float4 vertex : POSITION; // uv値 float2 uv : TEXCOORD0; }; // vertex to fragment構造体 struct v2f { // pos float4 vertex : SV_POSITION; // uv値 float2 uv : TEXCOORD0; }; // テクスチャ sampler2D _MainTex; // TRANSFORM_TEXの定数 float4 _MainTex_ST; // vert関数 v2f vert (appdata v) { v2f o; // クリップ座標に変換 o.vertex = UnityObjectToClipPos(v.vertex); // テクスチャのスケールとオフセット o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } // frag関数 fixed4 frag (v2f i) : SV_Target { // テクスチャのピクセルの色を返す fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }
今回は以上になります。
ご視聴ありがとうございました!