こんにちは、Unityエンジニアのオオバです。
前回に引き続きGLSL Sandbox作品をUnityに移植して遊んでみる記事です。
前回はGLSL Sandbox初期シェーダーコードでしたが、今回は色々と変更が入った作品を例に遊んでみます。

今回参考にした、煙がゆっくり流れるようなGLSL Sandboxの作品
GLSL Sandbox
変換後のシェーダーソース(Cg/HLSL)はコチラ
Smoke1.shader · GitHub
※不要そうなソースコードは削除されています。またパフォーマンスの観点からfloat、fixed型をhalf型に変更しています。

このような感じの成果物が出来ました。
ここから変換する上で何点かポイントを挙げます。
1. vert_img関数の使用
GLSL Sandboxはフラグメントシェーダーのみで完結しているサービスなので頂点シェーダーは、座標変換後の頂点をフラグメントシェーダーに渡すだけで良いです。
そこで頂点シェーダーにvert_img
を指定します。
CGPROGRAM
#pragma vertex vert_img
vert_img
はUnity側が用意しているUnityCG.cgincインクルードファイル内で定義された関数です。
◆UnityCG.cgincの一部ソース
...
struct appdata_img
{
float4 vertex : POSITION;
half2 texcoord : TEXCOORD0;
};
struct v2f_img
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
v2f_img vert_img( appdata_img v )
{
v2f_img o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv = v.texcoord;
return o;
}
...
このようにvert_img関数を使用すると、上記の定義済み構造体を使用し、座標変換後の頂点をフラグメントシェーダーに渡してくれるので非常に便利です。
half4 frag (v2f_img i) : SV_Target {
// fragment shader content
}
一方フラグメントシェーダーは v2f_img
型引数を定義しておくだけです。
2. vecとhalf, fixed, float型の違い
vec3 a = vec3(1.0);
というGLSLソースを、
half3 a = half3(1.0);
Cg/HLSLでこのように書いてはいけません。コンパイルエラーになります。
half3 a = half3(1.0, 1.0, 1.0);
正解はこちら。
このように引数を省略することは出来ません。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
まとめ
GLSLからCg/HLSL移植に関して、処理内容が難解なものはありますがルールと作法さえ理解すれば、変換自体はそこまで難しくはありません。
ただし実際のプロダクトで使用する場合はパフォーマンス改善をしないと厳しい場合が多いです。
ほとんどの作品がフラグメントシェーダー内でsin
, cos
などの関数を大量に使用しているため、GPU負荷は非常に高いと思われます。
使用する場合はご注意を。
iOS向けプロダクトであれば実機ビルドしてGPU負荷を見るのも良いかもしれません。

この記事が気に入ったらフォローしよう
- Unity5.5.0p1