Submit Search
シェーダーしよっ☆ Let's play shaders!
•
Download as KEY, PDF
•
93 likes
•
19,537 views
Yuichi Higuchi
Follow
How to make original shaders on cocos2d, and on Unity3D.
Read less
Read more
1 of 66
Download now
Downloaded 168 times
More Related Content
シェーダーしよっ☆ Let's play shaders!
1.
シェーダーしよっ OpenGL
ES, cocos2d, Unity
2.
シェーダーしよっ OpenGL
ES, cocos2d, Unity
3.
自己紹介
FREE! • xionchannel • @ajinotataki • Technical Artist ElectroMaster HungryMaster 18万本 5万本
4.
シェーダーとは
5.
描画パイプライン ソフトウェア処理(CPU処理)
・頂点座標 ・頂点番号リスト(ストリップ) ・法線 ・頂点カラー ・テクスチャのUV座標 など ハードウェア処理(GPU処理) OpenGL ES 1.0 固定パイプライン OpenGL ES 2.0 シェーダー ワールド変換 Vertex Shader ビュー変換 varying変数のラスタライズ 射影変換 ライティング Fragment Shader テクスチャマッピング 画面
6.
シェーダーとは • GPU用の色をつけるプログラム • VertexShaderとFragmentShaderがある •
OpenGLではGLSL言語を使う • シェーダーに与える引数もある Attribute, Uniform *後ほど説明します
7.
よくあるシェーダーの処理順 1. VertexShader
1. 頂点座標をProjection座標系に変換する →頂点座標を描画へ渡す 2. 法線をView座標系に変換して、ライティン グを行う →頂点の輝度をFragmentShaderへ渡す 3. UVをFragmentShaderへ渡す
8.
よくあるシェーダーの処理順 2. FragmentShader
1. VertexShaderから得られたUV値を元にテク スチャをフェッチしてピクセルの色を得る 2. VertexShaderから得られた輝度を乗算してピ クセルの色を変化させる 3. 得た色を描画へ渡す
9.
VertexShaderの仕組み (0,1)
(1,1) ポリゴンの頂点情報 *設定次第でこの情報量は変えられます Position (x, y, z) UV (u, v) Color (r, g, b, a) UV(0,0) (1,0)
10.
VertexShaderの仕組み C(0,1,1,0.5) D(1,0,0,0.5)
頂点の色を左のように 変えるとグラデーショ ンになる A(0,1,1,0.5) B(1,0,0,0.5)
11.
VertexShaderの仕組み
UV値をずらすと絵が (0+a,1) (1+a,1) スクロールします UV(0+a,0) (1+a,0)
12.
FragmentShaderの仕組み
UV(u’, v’) ピクセルの情報 *設定次第でこの情報量は変えられます UV (u, v) Color (r, g, b, a) これらが頂点間の位置 関係によって補間され て手に入る
13.
FragmentShaderの仕組み 得られたUV値を使って手に入った テクスチャカラーの色相を変える とこうなります。
14.
FragmentShaderの仕組み 得られたUV値を除算などで変化さ せると絵が荒くなります。 スーパーファミコンでよくあった 場面転換に使えそうですね。
15.
シェーダーで注意すべき点 •
staticな変数を持てない →その場限りで処理を考える • 他の頂点情報を参照できない →座標やUV値から処理してみる? • 他のピクセル情報を参照できない →引数として必要なテクスチャを用意する (フレームバッファを処理する場合など)
16.
Attribute, Uniform • AttributeはVertexShader用パラメータ
★ 頂点数分のデータが必要 (頂点座標、法線、頂点カラーなど) • Uniformは双方へのパラメータ ★ ピクセル分のデータではない ★ 全ピクセルに対して同じデータ (テクスチャ、演算用の値など)
17.
シェーダーの実例
18.
Gouraud, Phong •
頂点毎に陰影を計算して色付け(Gouraud, Lambertとも言う) • ピクセル毎に陰影を計算して色付け(Phong)
19.
Gouraud • Vertex Shaderでライトベクトルと頂点法
線ベクトルの内積を取って、光源に頂 点が向いているかどうかの度合いを計 算し、頂点の輝度とする • 光源に向いているほど明るくする
20.
Phong • Gouraudと同様の計算をFragment Shader
内で行うことで、ピクセル毎に光源に 向いているかを計算する • これによって頂点が荒くてもなめらか なシェーディングが計算できる
21.
Bump mapping •
法線情報をもたせたテクスチャを参照して、 ピクセル毎に凹凸計算をして陰影をつける • Normal mappingとも言う、法線マップとか
22.
Bump mapping • テクスチャに面法線からの相対法線情
報を描画したものを用意し、Fragment Shader内でピクセル毎に光源計算を行う • これによって頂点以外の細かい凹凸表 現ができるというもの
23.
Toon shading •
法線と光線の角度を元に陰影マップから陰影 色をピックアップすることで陰影に特徴を出 したものにしている(他の手法もある)
24.
Toon shading •
Vertex, Fragmentのどちらでもいいが、光源計 算後の輝度をそのまま使わずに、段階的に変 化するように加工する • 主に使われるものは、輝度をテクスチャのUV 値として採用して、輝度変化を別のテクス チャに描いておくもの
25.
Specular mask •
スペキュラーによる艶部分を減じるためにマ スクテクスチャを用意して、そのテクスチャ の値を考慮して艶の出具合を調整するもの
26.
Specular mask •
Fragment Shader内で、マスクテクスチャを参 照して、加算するスペキュラー値を調整して やることで、それぞれの箇所のスペキュラー の効果の強度が変化するようにする • たとえばマスクテクスチャの輝度をスペキュ ラー値に乗算するようにすれば、マスクテク スチャが暗い部分にはスペキュラーによる艶 は当たらないことになる
27.
その他
Rim Light Half Lambert Texture Blending Light Bloom
28.
OpenGL ES 2.0
での流れ glCreateShader() glShaderSource() glCreateProgram() glCompileShader() glAttachShader() glLinkProgram() 破棄してOK あとで使う glUseProgram()
29.
1. VertexShader, FragmentShaderのシェーダーオブ
ジェクトを作成 glCreateShader() 2. シェーダーオブジェクトにプログラムを読み 込む glShaderSource() 3. プログラムをコンパイル glCompileShader()
30.
4. プログラムオブジェクトを作成 glCreateProgram() 5.
プログラムオブジェクトにシェーダーを登録 glAttachShader() ※ここでシェーダーオブジェクトは破棄して良い 6. シェーダープログラムをリンク glLinkProgram() ※ここまで事前処理で良い 7. シェーダープログラムを適用 glUseProgram()
31.
cocos2dではどういう 流れになっているか
32.
cocos2d 2.0 での流れ self.shaderProgram
= [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTextureColor]; glCreateShader() glShaderSource() glCreateProgram() glCompileShader() glAttachShader() glLinkProgram() 破棄 初期化メソッド CC_NODE_DRAW_SETUP(); glUseProgram() drawメソッド
33.
初期化メソッドの流れ self.shaderProgram = [[CCShaderCache
sharedShaderCache] programForKey:kCCShader_PositionTextureColor]; [CCShaderCache sharedShaderCache] [[CCShaderCache alloc] init]; [self loadDefaultShaders]; [[CCGLProgram alloc] initWithVertexShaderByteArray:fragmentShaderByteArray:]; glCreateShader() glCreateProgram() glShaderSource() glAttachShader() glCompileShader() Attribute, Uniformの準備 glLinkProgram() 破棄
34.
初期化メソッドの流れ 1. [CCShaderCache sharedShaderCache]が呼ばれる 2.
その中で[[CCShaderCache alloc] init];が呼ばれる 3. その中で[self loadDefaultShaders];が呼ばれる 4. その中で[[CCGLProgram alloc] initWithVertexShaderByteArray: fragmentShaderByteArray: ];が呼ばれシェーダーが コンパイルされ、配列に保持
35.
5. さらにシェーダーのAttribute, Uniform指定用の
識別子を準備 (updateUniformsメソッド) 6. シェーダーをリンクし、4で生成されたプログ ラムは破棄 7. 4で保持されたシェーダーをCCNodeで使用する ために識別子がCCNode側のself.shaderProgram を渡す
36.
drawメソッドの流れ CC_NODE_DRAW_SETUP();
glUseProgram() glUniform*() 動的Uniformを更新 glBindTexture2d() 使用するテクスチャを指定 glVertexAttribPointer() Attributeメモリ座標を指定 glDrawArrays() ポリゴン描画
37.
drawメソッドの流れ 1. CC_NODE_DRAW_SETUP()マクロ内で glUseProgram()を実行、シェーダーが使用可能に
なる 2. 動的Uniformパラメータを更新 3. 使用テクスチャをBind 4. Attributeパラメータのメモリ座標をセット 5. ポリゴンを描画
38.
cocos2dでオリジナル シェーダーを使うには?
39.
初期化メソッドを変更 self.shaderProgram = [[CCShaderCache
sharedShaderCache] programForKey:kCCShader_PositionTextureColor]; [CCShaderCache sharedShaderCache] これを自前にして自前の [[CCShaderCache alloc] init]; シェーダーを登録する [self loadDefaultShaders]; [[CCGLProgram alloc] initWithVertexShaderByteArray:fragmentShaderByteArray:]; glCreateShader() glCreateProgram() glShaderSource() glAttachShader() glCompileShader() Attribute, Uniformの準備 glLinkProgram() 破棄
40.
drawメソッドの変更 CC_NODE_DRAW_SETUP();
glUseProgram() glUniform*() 動的Uniformを更新 glUniform*() 自前の動的Uniformを更新を追加 この辺に自 前パラメー glBindTexture2d() 使用するテクスチャを指定、自前のも追加 タを追加 glVertexAttribPointer() Attributeメモリ座標を指定、自前のも追加 glDrawArrays() ポリゴン描画
41.
というわけで 実際にやってみた
42.
法線マップを使用した 平行光源ライティングの例
43.
法線マップを使用した 点光源ライティングの例
44.
Unityでシェーダーを 使うにはどうするか?
45.
ShaderLab
46.
ShaderLab その1 • UnityはShaderLabという言語でシェー ダーを記述する •
ShaderLabは総合的な描画コントロール を行うためのもの (CgFXみたいな感じ)
47.
ShaderLab その2 • ShaderLab内にVertexShader,
FragmentShaderを記述することができる • その他Alpha Blend、描画順序、ZTest等 についても設定できる • LOD値に応じて使用シェーダーを分け ることができる、複数パスも記述可
48.
ShaderLab その3 • Unity上のパラメータとシェーダー側で 使用するパラメータを結びつけること
ができる • Unity上のパラメータ編集のためのUIを 構築できる
49.
.shaderファイルのサンプル
50.
パラメータの定義
51.
Tag設定 •
Queue : 描画順序 cf. “Geometry+1”など • RenderType : 描画方法 • LightMode : 指定すればライト値が更新される • これ以外にも機能はあります
52.
Pass設定 •
Lighting : ライティングの有無 • Cull : カリング指定 • ZWrite : Zバッファへの描画有無 • Blend : アルファブレンド指定 • これ以外にも機能はあります
53.
Vertex, Fragment Func
(Cg, GLSL) • CGPROGRAM∼ENDCG内にCgが書ける • GLSLPROGRAM∼ENDGLSL内にGLSLが書ける • #pragma指定でshading関数名を定義
54.
Fallback指定 •
Fallbackを指定することで定義したシェーダー が使用できない環境の場合に、Fallbackで指示 されたシェーダーを代わりに使用して描画す ることができる • ここに特殊なシェーダーを指定すると検索し きれずにエラーになってしまうこともあるの で要注意
55.
Surface Shader
56.
Surface Shaderとは • Surface
ShaderとはShaderLabの一番美味 しいところですが、ピーキーなシェー ダーを書こうと思う場合には不利かも • Vertex, Fragmentという分け方ではな く、質感と光源処理に分けてシェー ダーを記述する機能
57.
Surface Shaderのサンプル
58.
短いです
59.
Surface Func指定 •
surface [関数名] [ライティング名] • 定義済みのライティングモデルが使用できる cf. Lambertなど • 独自のライティング関数も定義可能 • finalcolorは最終的に色変更する関数定義 • vertexシェーダー関数も定義可能
60.
ShaderLabの参考web •
Surfaceシェーダーの参考web http://unity3d.com/support/documentation/ Components/SL-SurfaceShaderExamples.html • Cg, GLSLを使用する場合の参考 http://unity3d.com/support/documentation/ Components/SL-ShaderPrograms.html • ShaderLab全体の参考web http://unity3d.com/support/documentation/ Components/SL-Reference.html
61.
ShaderLabの参考web 2 •
MMD for Unity http://sourceforge.jp/projects/mmd-for-unity/devel/ • これに使われているシェーダーは機能と実装 がどうなっているかの取っ掛かりに良いと思 います。僕はこれで覚えました。
62.
ShaderLabのTIPS
63.
ライトカラーを参照するには Tag { "LightMode" =
"Vertex" } これを記述した上で、Vertex, Fragment関数内で unity_LightColor[0].rgbをつかってライト値を参照できます。 ライトベクトルはunity_LightPosition[0].rgbでいけます。 Surface Shaderを使用する場合は特に特殊な指定をしなくても そのあたりの値は引数からアクセスできます。
64.
実機でGLSLコンパイルが通らない件 struct v2f { float4
pos : SV_POSITION; fixed2 uv : TEXCOORD0; <これとか fixed custom : TEXCOORD1; <これとか half4 custom2; <これはだめ } コロン後にセマンティック指定をしてやらないと実機でGLSLがコンパイル される際にエラーになる可能性があります。 Unityのバグっぽいですけど、セマンティックが無いと同名の変数が定義さ れてしまうので、正しいコードとして解釈されないようです。
65.
実機だと描画結果が違う場合の対処 • 高速化のためにfixed変数を使いまくって いると、ものによっては演算精度が荒く
なりすぎて求めている結果にならない • 個別にhalfへ置き換えてなるべくfixedを残 した形でコードを書くのが良い • Mac等では現象が確認できないのが大変
66.
GLSLの参考資料 •
床井研究室 http://marina.sys.wakayama-u.ac.jp/~tokoi/? date=20051006 • 今回のソース(cocos2d) http://xionchannel.no-ip.org/ cocos2d_shaderTest.zip
Editor's Notes
#2:
\n
#3:
\n
#4:
\n
#5:
\n
#6:
\n
#7:
\n
#8:
\n
#9:
\n
#10:
\n
#11:
\n
#12:
\n
#13:
\n
#14:
\n
#15:
\n
#16:
\n
#17:
\n
#18:
\n
#19:
\n
#20:
\n
#21:
\n
#22:
\n
#23:
\n
#24:
\n
#25:
\n
#26:
\n
#27:
\n
#28:
\n
#29:
\n
#30:
\n
#31:
\n
#32:
\n
#33:
\n
#34:
\n
#35:
\n
#36:
\n
#37:
\n
#38:
\n
#39:
\n
#40:
\n
#41:
\n
#42:
\n
#43:
\n
#44:
\n
#45:
\n
#46:
\n
#47:
\n
#48:
\n
#49:
\n
#50:
\n
#51:
\n
#52:
\n
#53:
\n
#54:
\n
#55:
\n
#56:
\n
#57:
\n
#58:
\n
#59:
\n
#60:
\n
#61:
\n
#62:
\n
#63:
\n
#64:
\n
#65:
\n
#66:
\n
Download