Address
:
[go:
up one dir
,
main page
]
Include Form
Remove Scripts
Accept Cookies
Show Images
Show Referer
Rotate13
Base64
Strip Meta
Strip Title
Session Cookies
More Web Proxy on the site http://driver.im/
Submit Search
【TechBuzz】第9回cocos2d-x勉強会「シェーダ書いてますか?」
•
13 likes
•
7,811 views
N
nyagasuki
Follow
TechBuzzの第9回cocos2d-x勉強会での発表資料 https://atnd.org/events/61374
Read less
Read more
1 of 57
Download now
Downloaded 28 times
More Related Content
【TechBuzz】第9回cocos2d-x勉強会「シェーダ書いてますか?」
1.
シェーダ 書いてますか? 2015/01/27(Tue) Ryo Tsuruda
2.
Agenda ● 自己紹介 ● 本日の目的 ●
シェーダとは ● シェーダを見てみる ● シェーダを書いてみる ● まとめ
3.
自己紹介
4.
自己紹介 ● 名前:りょう ● 趣味:猫とプログラミング ●
仕事:ゲーム作り ○ 今まではサーバ、インフラ、ネイティブアプリなど ※今回の内容は、仕事とは関係なく趣味での発表です
5.
本日の目的
6.
本日の目的 ● シェーダとは何か?を知る ● Cocos2d-xでシェーダを書けるようになる ●
シェーダの仕組みの理解 やらないこと
7.
注意事項 ● シェーダのプロではないので、質問など答えら れない場合もあります ● Android/iOSで動作させるための
OpenGL ES のプログラマブルシェーダついての説明です ● Cocos2d-x v3.xでのみ動作確認しています
8.
シェーダとは
9.
シェーダとは ● GPUに命令して処理させるもの ● スクリーンに表示させる色を制御するもの 床井研究室 http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20090827
10.
シェーダとは 書いたことがある方?
11.
シェーダの例 ● トゥーンシェーダ ● ファーシェーダ ●
他多数
12.
シェーダの例 (cont.)
13.
シェーダの例 (cont.) !?
14.
シェーダの言語 ● シェーダを書くために必要な言語 ○ GLSL(OpenGL
Shading Language) ○ GLSL ES (OpenGL for Embedded System) ● 他には、 ○ DirectX : HLSL(High Level Shading Language) ○ NVIDIA : Cg ○ iOS : Metal Shading Language
15.
シェーダの言語 ● Cocos2d-xではどの言語を使っていますか? ○ C++
? ○ Lua ? ○ JavaScript ? ● どのbindingからも利用できます
16.
シェーダの処理の流れ 1. ノードを作成 (Sprite::create()) 2.
バーテックスシェーダ(Vertex Shader) ○ 頂点シェーダとも 3. フラグメントシェーダ(Fragment Shader) ○ ピクセルシェーダとも 4. 画面に表示 複数のシェーダで 処理
17.
シェーダを見てみる
18.
バーテックスシェーダ(Sprite) const char* ccPositionTextureColor_noMVP_vert
= STRINGIFY( attribute vec4 a_position; attribute vec2 a_texCoord; attribute vec4 a_color; n#ifdef GL_ESn varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; n#elsen varying vec4 v_fragmentColor; varying vec2 v_texCoord; n#endifn void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } ); ccShader_PositionTextureColor_noMVP.vert
19.
フラグメントシェーダ(Sprite) const char* ccPositionTextureColor_noMVP_frag
= STRINGIFY( n#ifdef GL_ESn precision lowp float; n#endifn varying vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); } ); ccShader_PositionTextureColor_noMVP.frag
20.
バーテックスシェーダ(解説) attribute vec4 a_position; attribute
vec2 a_texCoord; attribute vec4 a_color; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } attribute Cocos2d-xからバーテックスシェーダに渡される値 vec4 a_position 頂点情報 (Cocos2d-xでbindingしている変数) vec2 a_texCoord テクスチャのマッピング情報 (Cocos2d-xでbindingしている変数) vec4 a_color 色情報 (Cocos2d-xでbindingしている変数)
21.
バーテックスシェーダ(解説) attribute vec4 a_position; attribute
vec2 a_texCoord; attribute vec4 a_color; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } varying フラグメントシェーダに渡すための値 lopw / mediump 値の精度(floatとかdoubleと同じ) vec4 v_fragmentColor 色情報 vec4 v_texCoord テクスチャの情報
22.
バーテックスシェーダ(解説) attribute vec4 a_position; attribute
vec2 a_texCoord; attribute vec4 a_color; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } main() 最初に呼ばれる関数 gl_Position OpenGLで処理するポジション情報 CC_PMatrix 座標情報を調整するための変数 (Cocos2d-xでbindingしている変数)
23.
フラグメントシェーダ(解説) precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); } precision 精度の定義
24.
フラグメントシェーダ(解説) precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); } varying フラグメントシェーダから渡される値 vec4 v_fragmentColor 色情報 vec4 v_texCoord テクスチャの情報
25.
フラグメントシェーダ(解説) precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); } main() 最初に呼ばれる関数 gl_FragColor OpenGLで処理する色情報 CC_Texture0 テクスチャの情報(Cocos2d-xでbindingしている変数) texture2D() テクスチャから指定座標の色情報を抜き出す
26.
Cocos2d-xで定義されている変数 // uniform names const
char* GLProgram::UNIFORM_NAME_AMBIENT_COLOR = "CC_AmbientColor"; const char* GLProgram::UNIFORM_NAME_P_MATRIX = "CC_PMatrix"; const char* GLProgram::UNIFORM_NAME_MV_MATRIX = "CC_MVMatrix"; const char* GLProgram::UNIFORM_NAME_MVP_MATRIX = "CC_MVPMatrix"; const char* GLProgram::UNIFORM_NAME_NORMAL_MATRIX = "CC_NormalMatrix"; const char* GLProgram::UNIFORM_NAME_TIME = "CC_Time"; const char* GLProgram::UNIFORM_NAME_SIN_TIME = "CC_SinTime"; const char* GLProgram::UNIFORM_NAME_COS_TIME = "CC_CosTime"; const char* GLProgram::UNIFORM_NAME_RANDOM01 = "CC_Random01"; const char* GLProgram::UNIFORM_NAME_SAMPLER0 = "CC_Texture0"; const char* GLProgram::UNIFORM_NAME_SAMPLER1 = "CC_Texture1"; const char* GLProgram::UNIFORM_NAME_SAMPLER2 = "CC_Texture2"; const char* GLProgram::UNIFORM_NAME_SAMPLER3 = "CC_Texture3"; const char* GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE = "CC_alpha_value"; // Attribute names const char* GLProgram::ATTRIBUTE_NAME_COLOR = "a_color"; const char* GLProgram::ATTRIBUTE_NAME_POSITION = "a_position"; const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD1 = "a_texCoord1"; const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD2 = "a_texCoord2"; const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD3 = "a_texCoord3"; const char* GLProgram::ATTRIBUTE_NAME_NORMAL = "a_normal"; const char* GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT = "a_blendWeight"; const char* GLProgram::ATTRIBUTE_NAME_BLEND_INDEX = "a_blendIndex";
27.
シェーダを書いてみる
28.
真っ赤にしてみる attribute vec4 a_position; attribute
vec2 a_texCoord; attribute vec4 a_color; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; void main() { gl_Position = CC_PMatrix * a_position; - v_fragmentColor = a_color; + v_fragmentColor = vec4(1.0, 0.0, 0.0, 1.0); v_texCoord = a_texCoord; } バーテックスシェーダ
29.
?確かに赤いけど、真っ赤ではない
30.
バーテックスシェーダの役割 ● 頂点を決める ○ ポリゴンの頂点をどの位置に表示するか ○
表示する色を決めるのはフラグメントシェーダ void main() { gl_Position = CC_PMatrix * a_position; - v_fragmentColor = a_color; + v_fragmentColor = vec4(1.0, 0.0, 0.0, 1.0); v_texCoord = a_texCoord; } フラグメントシェーダに色情報を渡 しているだけ
31.
次こそ、真っ赤にしてみる precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { - gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } 表示される色を赤色に変更 (他の色情報は破棄)
32.
真っ赤になった シェーダが違う
33.
次はどうなるでしょうか? precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { - gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); + gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, vec2(v_texCoord.x/2.0, v_texCoord.y); } テクスチャから抽出する座標を変更
34.
見た目が半分なった
35.
シェーダの書き方 ● とにかく試行錯誤 ○ コンパイルエラーを出してくれる ○
型には厳密 ● 感覚 ○ 少しの調整で大きく変わることもある cocos2d: ERROR: 0:21: No matching function for call to texture2D(sampler2D, float) ERROR: 0:21: '/' does not operate on 'float' and 'int'
36.
シェーダの書き方 (cont.) ● 動的コンパイル ○
アプリのビルド時ではなく、実行時にコンパイル ○ コンパイルしたデータはキャッシュすること ○ リソースではなく、文字列としてコードに埋める ■ I/O待ちが発生するためCocos2d-xはこうしている ● デバッグ難しい ○ 実行して、コンパイルエラーをチェックしている ○ WebGLを試せるWebサービスなどで動作チェック ○ http://glslsandbox.com ● 実機で確認 ○ GPUを使っているので、実機での確認必須
37.
自作シェーダの適用 // スプライトの作成 auto sprite
= Sprite::create("HelloWorld.png"); this->addChild(sprite); // シェーダの読込みと適用 auto glProgram = GLProgram::createWithFilenames("shader.vert", "shader.frag"); auto glProgramState = GLProgramState::getOrCreateWithGLProgram(glProgram); sprite->setGLProgramState(glProgramState); // uniformに値を代入 glProgramState->setUniformVec2("touchPosition", touchPosition); uniform プログラムからバーテックスシェーダやフラグメントシェーダに渡される値
38.
グレイスケール(vert) attribute vec4 a_position; attribute
vec4 a_color; attribute vec2 a_texCoord; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; void main(void) { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
39.
グレイスケール(frag) precision lowp float; varying
vec4 v_fragmentColor; varying vec2 v_texCoord; // Gray scale(RGB) const vec3 grayScale = vec3(0.298912, 0.586611, 0.114478); void main(void) { vec4 color = texture2D(CC_Texture0, v_texCoord); float grayScaleColor = dot(color.rgb, grayScale); gl_FragColor = vec4(vec3(grayScaleColor), color.a); }
40.
グレイスケール
41.
ブラー(vert) varying vec2 v_texCoord; varying
vec2 v_blurTexCoords[14]; uniform float u_rate; void main() { gl_Position = CC_PMatrix * a_position; v_texCoord = a_texCoord; v_blurTexCoords[ 0] = v_texCoord + vec2(-0.028 * u_rate, 0.0); v_blurTexCoords[ 1] = v_texCoord + vec2(-0.024 * u_rate, 0.0); v_blurTexCoords[ 2] = v_texCoord + vec2(-0.020 * u_rate, 0.0); v_blurTexCoords[ 3] = v_texCoord + vec2(-0.016 * u_rate, 0.0); v_blurTexCoords[ 4] = v_texCoord + vec2(-0.012 * u_rate, 0.0); v_blurTexCoords[ 5] = v_texCoord + vec2(-0.008 * u_rate, 0.0); v_blurTexCoords[ 6] = v_texCoord + vec2(-0.004 * u_rate, 0.0); v_blurTexCoords[ 7] = v_texCoord + vec2( 0.004 * u_rate, 0.0); v_blurTexCoords[ 8] = v_texCoord + vec2( 0.008 * u_rate, 0.0); v_blurTexCoords[ 9] = v_texCoord + vec2( 0.012 * u_rate, 0.0); v_blurTexCoords[10] = v_texCoord + vec2( 0.016 * u_rate, 0.0); v_blurTexCoords[11] = v_texCoord + vec2( 0.020 * u_rate, 0.0); v_blurTexCoords[12] = v_texCoord + vec2( 0.024 * u_rate, 0.0); v_blurTexCoords[13] = v_texCoord + vec2( 0.028 * u_rate, 0.0); }
42.
ブラー(frag) varying vec2 v_texCoord; varying
vec2 v_blurTexCoords[14]; void main() { gl_FragColor = vec4(0.0); gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 0])*0. 0044299121055113265; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 1])*0.00895781211794; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 2])*0.0215963866053; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 3])*0.0443683338718; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 4])*0.0776744219933; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 5])*0.115876621105; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 6])*0.147308056121; gl_FragColor += texture2D(CC_Texture0, v_texCoord )*0.159576912161; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 7])*0.147308056121; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 8])*0.115876621105; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[ 9])*0.0776744219933; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[10])*0.0443683338718; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[11])*0.0215963866053; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[12])*0.00895781211794; gl_FragColor += texture2D(CC_Texture0, v_blurTexCoords[13])*0. 0044299121055113265;
43.
ブラー
44.
ノイズ(vert) attribute vec4 a_position; attribute
vec4 a_color; attribute vec2 a_texCoord; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main(void) { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
45.
ノイズ(frag) varying vec4 v_fragmentColor; varying
vec2 v_texCoord; uniform vec2 resolution; const float intensity = 0.05; vec3 noise(vec2 uv) { vec2 p = abs(sin(uv * 13.0 + uv.x * CC_Time[1] * sin(uv.y))); return vec3(sin (0.2 * CC_Time[1] + sin(p * 0.5) * CC_Time[1] / cos(50.0)) * 10.0,0.3+0.5 * abs(sin (CC_Time[1] * tan(5.0)))); } void main(void) { gl_FragColor.xyz = intensity * noise(gl_FragCoord.xy / sin(resolution.xy * CC_Time[1] * 0.01)) + (1. - intensity) * texture2D(CC_Texture0,v_texCoord.xy).xyz; gl_FragColor.w = 1.; }
46.
ノイズ
47.
旗(vert) attribute vec4 a_position; attribute
vec4 a_color; attribute vec2 a_texCoord; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main(void) { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
48.
旗(frag) #ifdef GL_ES precision mediump
float; #endif varying vec2 v_texCoord; void main( void ) { float len = length(v_texCoord); vec2 uv = vec2(v_texCoord.x - (v_texCoord.x / len) * cos(len - CC_Time[1]) * 0.05, v_texCoord.y - (v_texCoord.y / len) * sin(len * 12.0 - CC_Time[1] * 7.0) * 0.05); gl_FragColor = texture2D(CC_Texture0, uv); }
49.
旗
50.
波(vert) attribute vec4 a_position; attribute
vec4 a_color; attribute vec2 a_texCoord; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main(void) { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
51.
波(frag) #ifdef GL_ES precision highp
float; #endif uniform vec2 resolution; uniform vec2 touchPosition; varying vec2 v_texCoord; void main(void) { vec2 tc = v_texCoord; vec2 p = vec2(tc.x-touchPosition.x, tc.y-touchPosition.y); float len = length(p); vec2 uv = tc + (p / len) * cos(len * 14.0 - CC_Time[1] * 8.0) * 0.04; vec3 col = texture2D(CC_Texture0, uv).xyz; gl_FragColor = vec4(col, 1.0); }
52.
波
53.
GLES Sandboxより(vert) attribute vec4
a_position; attribute vec4 a_color; attribute vec2 a_texCoord; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main(void) { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
54.
GLES Sandboxより(frag) http://glslsandbox.com/e#22390.2
55.
画像が別物に
56.
まとめ
57.
まとめ ● 次のステップに向けて ○ 今回は超基本なので、本格的なものは勉強が必要 ○
数学の知識が必要となることが多いです ● 差別化 ○ シェーダを自作すると、大きな差別化を図れる ○ コンソール出身の方が作るゲームには自作シェーダが 多いのではないでしょうか
Download