こんにちは、Unityエンジニアのオオバです。
GLSL Sandboxとは、
言わずと知れた有名なWebサービスです。
GLSLで書かれたシェーダーを即時実行して全世界にブラウザベースで共有できます。
ソースも公開されているためシェーダー教材としても非常に重宝します。
実際にUnityで試してみたい表現が見つかったりするので移植することもありますが、
そもそもUnityはShaderLabという独自のシェーダー言語
なので単純にコピペという訳にはいきません。
本記事では移植方法について説明していきます。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
シェーダー言語が違う
先ほど説明したとおり、Unityのシェーダーは全てShaderLab
で
記述されていて、記述文法としてはCg/HLSL
です。
ということで、GLSL SandboxのGLSLコードをCg/HLSLに変換します。
GLSL Sandbox初期ソースをCg/HLSLに変換
GLSL Sandboxで新規作成したときのGLSLコード
newglslsandbox.glsl · GitHub
こちらのGLSLをUnityに以下の手順で移植してみます。
- 不要ソース削除
- フラグメントシェーダー処理をコピペする
- Cg/HLSLの文法に書き換える

1.不要ソース削除
こちらのソースは使用しないので削除します。
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform
と付くものは外部(ここではJavaScript)から渡される変数で、
time
・mouse
・resolution
はそのまま、
時間
・マウス座標
・解像度
が渡ってきます。
マウス座標以外はShaderLab内で取得可能なので、ここでは削除します。
2. フラグメントシェーダー処理をコピペする
void main( void ) {
// fragment shader content
}
11行目のmain関数
がフラグメントシェーダー処理です。
この中身をUnityのフラグメントシェーダーにコピペします。
それ以外の変数や関数、構造体などのコードを
フラグメントシェーダーより手前
にコピペします。
このサンプルにはmain関数しか無いので、
該当する変数・関数はありませんが、大抵この作業は発生します。
※使用する関数・変数・定数・構造体は、
C言語のように使用するコードより先に書いてないとコンパイルエラー
3.Cg/HLSLの文法に書き換える
ただコピペするだけだとコンパイルエラーになるので、ここからCg/HLSL文法に変換していきます。
フラグメントシェーダーおさらい
フラグメントシェーダーはピクセル毎に処理していくユニットです。
最終的にそのピクセルのカラー値を算出することで処理を終えます。
GLSLとCg/HLSLでは少し文法が違うのでおさらいです。
■GLSLの場合
GLSLのフラグメントシェーダーはgl_FragColor
変数にカラー(vec4型)を代入します。
gl_FragColor = vec4( vec3( color, color * 0.5, sin( color + time / 3.0 ) * 0.75 ), 1.0 );
■Cg/HLSLの場合
一方Cg/HLSLのフラグメントシェーダーでは、
returnステートメント
でカラー(fixed4型、float4型、half4)を返却します。
return fixed4( fixed3( color, color * 0.5, sin( color + time / 3.0 ) * 0.75 ), 1.0 );
また適宜以下のようにキーワードを置き換えてコンパイルが通るように修正していきます。
GLSL | Cg/HLSL | 備考 |
---|---|---|
vec | half, fixed, float | |
_time | _Time | |
mix | lerp | 線形補間 |
fract | frac | 引数の小数部分を返す |
mat2 | half2x2, fixed2x2, float2x2 | 2☓2行列 |
mat3 | half3x3, fixed3x3, float3x3 | 3☓3行列 |
mat4 | half4x4, fixed4x4, float4x4 | 4☓4行列 |
resolution | _ScreenParams | 解像度 |
fragCoord | i.uv*_ScreenParams | 頂点シェーダー定義済み関数vert_img を定義した場合 |
mouse | - | C#からシェーダーに値を引き渡して実装する |
更に詳しくはコチラのサイトをどうぞ
頂点シェーダー関数をvert_imgに設定する
これはやってもやらなくても良いのですが、UnityCG.cgincに頂点を変換するだけのミニマムな定義済み頂点シェーダー関数が定義されています。
#pragma vertex vert_img
vert_imgを使用することで、頂点シェーダー関数の記述を省くことが出来ます。
fixed4 frag (v2f_img i) : SV_Target
以下のようにvert_img
関数がv2f_img
を返却しているため、上記のようにフラグメントシェーダーの引数はv2f_img
構造体にする必要があります。
UnityCG.cginc内vert_img関数のソースコード
v2f_img vert_img( appdata_img v )
{
v2f_img o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv = v.texcoord;
return o;
}
変換終了
最終的にこのようなソースコードになります。
書いたシェーダーの反映方法の例

Quad(板ポリ)を1枚3D上に配置します。

先程のシェーダーをMaterialにアタッチして、このQuadにアタッチします。

すると、このようにシェーダーを反映できます。
次回は初期コードではない、もう少しコード量の多いシェーダーを移植してみます。
余談:float4, half4, fixed4とは何か?
さっきからよく出てきてますが、どれも同じ4つの要素を持った値ですが、違いは精度です。
型 | 精度 | 備考 |
---|---|---|
float | 高精度の32bit浮動小数点 | 通常プログラミングのfloatと同じような32bit |
half | 中精度16bit浮動小数点 | –60000 から +60000 の範囲で、小数点以下約 3 桁 |
fixed | 低精度11bit固定小数点 | –2.0 から +2.0 の範囲で、1/256の精度 |
int型も使えるようですが、プラットフォームによってはサポートされていないGPUがあるようで注意です。

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