前回のエントリーに引き続いて、「頂点 + フラグメントシェーダー」を勉強していきます。 サーフェイスシェーダーを使った場合と違いかなり複雑になっています。 細かな調整をする場合には、こちらを使ったほうが良いと思うのですが、今のところ使う用途がよくわからないのが現状ですね。
テクスチャ処理
テクスチャを指定してオブジェクトに表示をします。 サーフェイスシェーダー同様、プロパティから利用するテクスチャを指定します。 [c] struct vertout { float4 pos : POSITION; float2 TexCoord : TEXCOORD0; // テクスチャ float3 Normal : TEXCOORD2; float3 lightDir : TEXCOORD3; float3 viewDir : TEXCOORD4; LIGHTING_COORDS(5,6) };
// テクスチャをtextcoordに変換する vertout vert(appdata_full v) { vertout OUT; OUT.pos = mul(UNITY_MATRIX_MVP,v.vertex); OUT.TexCoord = TRANSFORM_TEX(v.texcoord,Texture); //テクスチャを変換 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; } // テクスチャの色をcolorへ代入します。 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 tex = tex2D(Texture,In.TexCoord); float4 color =tex * UNITY_LIGHTMODEL_AMBIENT + (tex * LightColor0 * diffuse + LightColor0 * half4(1.0,1.0,1.0,1.0) * specular) * atten; return color; } [/c]
バンプマッピング処理
法線マッピングを行います。 表面の凸凹を検出して、色つけていきます。 [c] sampler2D Bump; float4 Bump_ST;//ST座標
// vertout内 float3 TangentRX : TEXTCOORD3; float3 TangentRY : TEXTCOORD4; float3 TangentRZ : TEXTCOORD5; [/c]
vert内 [c] //接空間への、3x3の行列を生成するマクロのようです。 //v.tangent.xyzは接ベクトル、そこから従法線を求め、最終的に3x3の行列にしています。 TANGENT_SPACE_ROTATION;
//テクスチャから正規化された法線を取り出します。 OUT.TangentRX = mul(rotation,Object2World[0].xyz); OUT.TangentRY = mul(rotation,Object2World[1].xyz); OUT.TangentRZ = mul(rotation,_Object2World[2].xyz);
[/c]
UV座標:テクスチャ上の座標 ST座標:テクスチャトランスフォーム後のテクスチャ上の座標
3D描画基礎知識 - SSSSLIDE CG - [Unity] Vertex/Fragment shaderで通常のライティングとシャドウを適用するサンプル - Qiita
鏡面
reflect関数を使用します。 [c] float4 reflectVec; reflectVec.xyz = reflect(-In.viewDir,normal); reflectVec.w = 1; float4 emssion = texCUBE(CubeMap,reflectVec); [/c] ここで導き出された色をcolorに付け足して上げます。 [c] float4 color = (UNITY_LIGHTMODEL_AMBIENT + (Diffuse * LightColor0 * diffuse + LightColor0 * half4(1.0,1.0,1.0,1.0) * specular) * atten) + emssion; [/c] Shaderific - GLSL Functions
ガラス
今度は「ガラス」の表面をオブジェクトへ適応させていきます。 refract関数を使います。 [c] float4 refractVec; refractVec.xyz = refract(In.viewDir,normal,0.667); refractVec.w = 1; float4 refractColor = texCUBE(_CubeMap,reflectVec); //色 float4 refractPower = pow(dot(In.viewDir,normal),3); //屈折 float4 reflectPower = pow(1.0 - dot(In.viewDir,normal),1.5); //反射 [/c]
Unity 5 実践シェーダプログラミング入門 [改訂第一版] 高橋 潤 売り上げランキング : 2985 Amazonで詳しく見る |