【Unity】頂点+フラグメントシェーダープログラミング 1

  • |
【Unity】頂点+フラグメントシェーダープログラミング 1
   

サーフェイスシェーダーに関しては、Unity(シェーダー?)側で色々とやってくれるおかげで、コード量が少なくなっていましたが、「頂点+フラグメントシェーダー」は色々と記載をしていく必要があります。
サーフェイスシェーダーと同じように以下のような形式でシェーダーを書いていきます。

Shader "Custom/Empty" {
    SubShader {
        Pass {
            CGPROGRAM
            ENDCG
        }
    }
}

頂点 + フラグメントシェーダー

まずは、頂点とフラグメントをりようできるようにします。
// 各頂点について実行され、出力は、フラグメントシェーダに渡される
 #pragma vertex vert
// 各ピクセル毎に実行されるシェーダプログラムです。
 #pragma fragment frag

指定した「頂点 + フラグメント」関数に必要な処理を記載します。
// 入力:float v:POSITION 頂点の値
// 出力:float4 :SV_POSITION 2Dウィンドウ中の座標
float4 vert (float4 v:POSITION) : SV_POSITION{
    return mul(UNITY_MATRIX_MVP,v);
}

// フラグメント処理
// 出力はカラー RGBA (赤、緑、青、アルファ)を含む fixed4 変数で定義される COLOR 値として定義されます。
fixed frag() : COLOR{
   return fixed4(1.0,0.0,0.0,1.0); // 赤を出力
}

拡散

光を適応させるためのタグを設置します。
// タグ
Tags{"LightMode" = "ForwardBase"}
Unity – マニュアル: ShaderLab: Pass タグ

// ForwardBaseでのコンパイラ
#pragma multi__compile_fwdbase
// フラグメント処理で、できるだけ精度を下げて実行時間を最小限に抑えたいときのオプション(GPU)
#pragma fragmentoption ARB_precision_hint_fastest
Unity – マニュアル: 複数のシェーダープログラムのバリアントを作る

必要なincludeファイルを読み込みます。
#include "UnityCG.cginc"
#include "AutoLight.cginc" //ライティングやシャドウ機能
<a href="http://docs.unity3d.com/ja/current/Manual/SL-BuiltinIncludes.html" target="_blank">Unity - マニュアル: ビルトインシェーダー include ファイル</a>

//ライトの色を受け取る変数
float4 _LightColor0;

頂点データの出力

vertexから、頂点データの出力情報を取り出す構造体を作成します。
これを使って、フラグメントシェーダーを利用します。
struct vertout{
	float4 pos:SV_POSITION; //2Dウィンドウの座標
	float3 Normal:TEXCOORD0; // 法線ベクトル
	float3 lightDir:TEXCOORD1; // ライトへのベクトル
	float3 viewDir:TEXCOORD2; // カメラへのベクトル
	LIGHTING_COORDS(3,4) //Unityのライディング支援関数で利用する
};

関数の定義

vertexとfragmentの各関数の定義を行います。
vertout vert(appdata_full v){
   vertout OUT;
   OUT.pos = mul(UNITY_MATRIX_MVP,v.vertex);
   OUT.Normal = normalize(v.normal).xyz;
   OUT.lightDir = normalize(ObjSpaceLightDir(v.vertex));
   OUT.viewDir = normalize(ObjSpaceViewDir(v.vertex));

   TRANSFER_VERTEX_TO_FRAGMENT(OUT);
   return OUT;
}

fixed4 frag(vertout In):COLOR{
	fixed atten = LIGHT_ATTENUATION(In);
	float diffuse = max(0,mul(In.lightDir,In.Normal));
	float specular = max(0,mul(normalize(In.viewDir + In.lightDir),In.Normal));
	specular = pow(specular,30);
	float4 color = UNITY_LIGHTMODEL_AMBIENT + (_Diffuse * _LightColor0 * diffuse + _LightColor0 * half4(1.0,1.0,1.0,1.0) * specular) * atten;
	return color;
}
Shadew  1

2つ以上のPassを設定

複数のライトに対応させるために、Passを2つ増やしましょう。
// 2つめ以降のタグは以下のようにする
Tags{"LightMode" = "ForwardAdd"}
Blend One One
Light  1


【参考】


Unity 5 実践シェーダプログラミング入門 [改訂第一版]Unity 5 実践シェーダプログラミング入門 [改訂第一版]
高橋 潤

売り上げランキング : 5938

Amazonで詳しく見る

Related Posts Plugin for WordPress, Blogger...