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

サーフェイスシェーダでもできる「アルファ」と「オブジェクトの修正」を行います。 さらに、「ジオメトリシェーダー」を使ったポリゴンの修正を勉強してみました。

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

売り上げランキング : 6451

Amazonで詳しく見る
Geo  1

アルファ

透明度を変更する場合は、COLORのアルファ部分に値を設定します。 [c] //レンダリングキュー[Transparent] : オブジェクトを描画する順番を設定 // RenderType [Transparent] : ほとんどの部分的に透過なシェーダー Tags{"Queue" = "Transparent" "RenderType" = "Transparent"} Pass{ //アルファブレンドを設定する Blend SrcAlpha OneMinusSrcAlpha fixed4 frag(vertout In) : COLOR{ // カメラの視点と法線の内積を計算をして、透明度を調整しています。 float alpha = pow(max(0,dot(In.viewDir,In.normal)),3); float4 color = _Color; color.a = alpha; // アルファを設定 return color; } } [/c]

Unity - マニュアル: ShaderLab :サブシェーダータグ Unity - マニュアル: Replaced Shaders でのレンダリング Alpha blending

頂点データの修正

シェーダーを使ってオブジェクトの頂点情報を修正することができます。

[c] vertout vert (appdata_full v){ vertout OUT; // 頂点の位置をTimeを使って時間が経つごとに変更しています。 v.vertex.x += 0.05 * v.normal.x * sin*1; OUT.viewDir = normalize(ObjSpaceViewDir(v.vertex));

TRANSFER_VERTEX_TO_FRAGMENT(OUT); return OUT; } [/c] [Unity] シェーダで使える定義済値 - Qiita

ジオメトリシェーダー

ジオメトリシェーダーを利用する場合に、まず定義をします。 [c] // 関数名を定義する

pragma geometry geo

[/c]

ポリゴンを分割するためのメソッドを定義します。 [c] float4 setPos(float s, float t, float4 pos1, float4 pos2, float4 pos3) { float4 pos = pos1 + (pos2 - pos1) * s + (pos3 - pos1) * t; // 3点の中間位置を求める return pos; } [/c]

1つのポリゴンの分割数を設定する。 [c] // 三角形4つなので、12 [maxvertexcount(12)]

// ジオメトリの関数の中身を記載します。 // 頂点のシェーダーから、三角のポリゴンを出力します。 void geo(triangle vertout In[3], inout TriangleStream TriStream) { //頂点シェーダから、ポリゴンに必要な頂点を求める   pos[0] = setPos(0,0,In[0].pos,In[1].pos,In[2].pos); pos[1] = setPos(0.5,0,In[0].pos,In[1].pos,In[2].pos); //... //... //...

// 頂点から法線を求めます。    //求めた頂点からポリゴンを導きます。 TriStream.Append(geoOutMethod(pos[0],nor[0])); TriStream.Append(geoOutMethod(pos[1],nor[1])); //... //... //...

} [/c]

流れはこのようなのですが、複雑な感じがします。 ジオメトリシェーダーを使えば、より滑らかなアニメーションが表現できます。

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

売り上げランキング : 6451

Amazonで詳しく見る

*1:v.vertex.y + Time.x * 3) * 3.14 * 8); v.vertex.z += 0.05 * v.normal.z * sin((v.vertex.y + _Time.x * 3) * 3.14 * 8);

OUT.pos = mul(UNITY_MATRIX_MVP,v.vertex); OUT.Normal = normalize(v.normal).xyz; OUT.lightDir = normalize(ObjSpaceLightDir(v.vertex