読者です 読者をやめる 読者になる 読者になる

渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きく慣れるように。。。 ※所属団体とは一切関係がありません

GLSL SandboxをUnityに移植する方法その1


f:id:esakun:20161214013319p:plain

環境

  • Unity5.5.0p1

glslsandbox.com

GLSL Sandboxは、言わずと知れた有名なWebサービスです。
GLSLで書かれたシェーダを即時実行して全世界にブラウザベースで共有できます。

ソースも公開されているためシェーダ教材としても非常に重宝します。

実際にUnityで試してみたい表現が見つかったりするので、移植することもありますが一筋縄ではいかないため、本記事では移植方法について説明していきます。

シェーダ言語が違う

Unityのシェーダは全てShaderLabという言語で記述されていて、Cg/HLSLでシェーダコードを書くことが出来ます。
※厳密にはGLSLでも記述可能ですが、「クロスコンパイルの観点からGLSLはテスト版のみで、プロダクトとしてはCg/HLSLで書いてね」と公式リファレンスにも書かれています。

docs.unity3d.com

ということで、GLSL SandboxのGLSLコードをCg/HLSLに変換します。

GLSL Sandbox初期ソースをCg/HLSLに変換

まずはGLSL Sandboxの新規エフェクトを作る時に生成されるデフォルトGLSLコードをUnityに移植してみます。

gist.github.com

こちらのソースがGLSL Sandboxの新規ソースです。

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)から渡される変数で、timemouseresolutionはそのまま、時間マウス座標解像度が渡ってきます。マウス座標以外はShaderLab内で取得可能なので、ここでは削除します。

2. フラグメントシェーダ処理をコピペする

void main( void ) {
// fragment shader content
}

11行目のmain関数がフラグメントシェーダ処理です。
この中身をUnityのフラグメントシェーダにコピペします。

それ以外の変数や関数などのコードをフラグメントシェーダより手前にコピペします。このサンプルにはmain関数しか無いので、該当する変数・関数はありませんが、大抵この作業は発生します。
※使用する関数・変数・定数は、使用するコードより先に書いてないとコンパイルエラーになります

3.Cg/HLSLの文法に書き換える

ただコピペするだけだとコンパイルエラーになるので、ここから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型)が、ピクセルカラーとして指定されます。

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*30 30はフレームレート
mix lerp
fract frac
mat2 half2x2, fixed2x2, float2x2
mat3 half3x3, fixed3x3, float3x3
mat4 half4x4, fixed4x4, float4x4
resolution _ScreenParams 解像度
fragCoord i.uv*_ScreenParams vert_imgを定義した場合
mouse - C#からシェーダに値を引き渡す

更に詳しくはコチラのサイトをどうぞ

opengl:glsl_hlsl [HYPERでんち]

※ちなみにGLSLSandboxはフラグメントシェーダのみで表現されていますので、頂点シェーダでは、ただ単純に座標変換するだけの処理にします。

変換終了

最終的にこのようなソースコードになります。

gist.github.com

■ 書いたシェーダの反映方法

f:id:esakun:20161213235306p:plain

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

f:id:esakun:20161213235141p:plain

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

f:id:esakun:20161213234937p:plain

すると、このようにシェーダを反映できます。

※マウスの値を反映していないので表現に差異が発生していると思います。あくまでプロセスとして参考にしてください。

次回は初期コードではない、もう少しコード量の多いシェーダを移植してみます。

あわせてどうぞ

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info