Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WebGL2入門
Search
Rintarooo
November 11, 2023
Programming
0
72
WebGL2入門
Rintarooo
November 11, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
500
Cap'n Webについて
yusukebe
0
150
Jetpack XR SDKから紐解くAndroid XR開発と技術選定のヒント / about-androidxr-and-jetpack-xr-sdk
drumath2237
1
200
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
4
990
gunshi
kazupon
1
120
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
190
PostgreSQLで手軽にDuckDBを使う!DuckDB&pg_duckdb入門/osc25hi-duckdb
takahashiikki
0
200
Navigating Dependency Injection with Metro
l2hyunwoo
1
190
チームをチームにするEM
hitode909
0
400
re:Invent 2025 のイケてるサービスを紹介する
maroon1st
0
150
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
200
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
670
Featured
See All Featured
How to Talk to Developers About Accessibility
jct
1
87
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
120
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
2.8k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
91
For a Future-Friendly Web
brad_frost
180
10k
We Are The Robots
honzajavorek
0
120
The Invisible Side of Design
smashingmag
302
51k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
53
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
340
Transcript
WebGL2 Tutorial 1 @Rintarooo 2023/11/11
コンテンツ Contents • WebGLとは • Hands-on⓪ • Hands-on① • シェーダーとは
• Hands-on② • レンダリングパイプライン • Hands-on③ • VBO, IBO and VAO • Hands-on (optional) 2
参考 オライリー・ジャパン 「初めてのWebGL2」 & ネットに落ちてる技術系ブログ・講義スライド 3 GPU並列図形処理入門 コンピュータ グラフィックス
WebGLとは 4
WebGLとは • Javascriptで呼び出せる(Webブラウザ上で動く)グラフィックスAPI。 • 呼び出す上で、ライブラリのインストールやプラグインは不要。 5
WebGLとは グラフィックスAPIとは? 6 • Javascriptで呼び出せる(Webブラウザ上で動く)グラフィックスAPI。 • 呼び出す上で、ライブラリのインストールやプラグインは不要。
まかせろ〜! WebGLとは • Javascriptで呼び出せる(Webブラウザ上で動く)グラフィックスAPI。 • 呼び出す上で、ライブラリのインストールやプラグインは不要。 Javascript グラフィックスAPIとは? こんな感じの絵を 描いてくれ〜!
7 WebGL
WebGLとは • Javascriptで呼び出せる(Webブラウザ上で動く)グラフィックスAPI。 • 呼び出す上で、ライブラリのインストールやプラグインは不要。 グラフィックスAPIとは? 8 • WebGLはライブラリではなく, 「みんな〜!こういう風に実装しようね!」という、仕様書※のようなもの。
• 実際に実装されるAPIの内部処理は、Intel, NVIDIA, AMDなどの CPUやGPUの開発会社(ベンダー)に委ねられる。(差はほぼ無いらしい) 参考:OpenGLは普通のライブラリとは違う グラフィックスの基礎 ※仕様を策定している非営利団体:Khronos Group
WebGLの位置付け 図引用:WebGLのなりたち 9 (OpenGLの派生。 ES=組み込み スマホで動かせるように。 ) (OpenGL ESの派生。 ブラウザ上で動かせるように。
) 2016年に、WebGLからWebGL2へ移行。 ネット記事に両方の情報が混在。
WebGLの位置付け (Appleが開 発元) 抽象度 (下に行くほどローレベル) PyOpenGL • WebGLは、ローレベル※なAPI • 抽象度の高いライブラリやCG系のソ
フトは、描画する際に、 内部的にローレベルのAPIを呼び出 すこともある (Direct3D) (Microsoftが 開発元) 参考:WebGLのなりたち ライブラリ グラフィックスAPI CG系のソフト 10 抽象化 派生 派生 DirectX 12 ※ローレベル =ハードウェア側に近い。 結果として、コードの記述量が多くなる。
Three.jsでもこんなの作れる Three.jsのサンプル例 → https://threejs.org/examples/#webgl_animation_keyframes 11
なぜWebGLを学ぶ? • より抽象度の高い便利なCGソフトやライブラリを勉強する時、 ◦ WebGLのような、ローレベルAPIに触れておくことで、 内部処理の知識を流用して、安易に扱えれるようになる◎ • 一方、WebGLではなく、 ◦ Vulkanだと、
▪ ローレベル過ぎて、学習コストがあまりにも高過ぎる。 ◦ OpenGLだと、 ▪ WebGLと比べて、環境作るハードル高め (GLFW, GLADなどのライブラリ要る)。 ▪ Apple、独自のMetalなどのAPIへの移行を推奨 参考:OpenGLを勉強する必要はあるのか 12
Hands-on⓪ Canvasを作ろう 13
まかせろ〜! Canvasとは • WebGLが描画した絵を表示する領域 Javascript こんな感じの絵を 描いてくれ〜! 14 WebGL
描いたぞ! Canvasとは • WebGLが描画した絵を表示する領域 Javascript WebGLが 描いた絵 15 WebGL
Canvasとは • WebGLが描画した絵を表示する領域を、用意してあげる Javascript WebGLが 描いた絵 どこに絵を 表示しよう??? 16 WebGL
描いたぞ!
Canvasとは • WebGLが描画した絵を表示する領域(=Canvas)を、用意してあげる Javascript WebGLが 描いた絵 Canvasってとこに表 示するか〜 17 WebGL
描いたぞ!
Hands-on⓪ : Canvasを作ってみる $ git clone https://github.com/Rintarooo/WebGL2-tutorial 18 1. ターミナルからリポジトリをクローン
Hands-on⓪ : Canvasを作ってみる 19 3. `src/sample0_hello_world_canvas/index.html`を右クリックして、 Live Serverで開く $ code
WebGL2-tutorial/ 2. codeコマンドで、VSCodeで開く (VSCodeユーザ向け) VSCodeの拡張機能であるLive Server
Hands-on⓪ : Canvasを作ってみる 20 2. VSCode以外のユーザーは、Pythonの標準のhttpパッケージの serverモジュール使って、ローカルサーバーを起動 $ python3 -m
http.server 3000 参考:簡単なローカルサーバーの立て方 (非VSCodeユーザ向け※ ) $ cd WebGL2-tutorial/src/sample0_hello_world_canvas 3. 指定したポート番号(この例だと、3000)に、ブラウザから `http://localhost:3000`にアクセス ※Macのopenコマンドは、後にモジュールをimportしたjsを使う時 にエラーになるので非推奨
Hands-on⓪ : Canvasを作ってみる 21 こういうのが、ブラウザ上で表示出来ると成功。
Canvasとは(厳密には) • WebGLが描画した絵を表示する領域を、用意してあげる Javascript Canvasってとこに表 示するか〜 22 厳密には、javascript内で Canvasを作っているのではなく、 html・css内で宣言・定義したCanvasに、
javascriptからアクセスしている。
まだWebGL出てきてない、、 23
Hands-on① Hello World! WebGL 24
Hands-on① : Hello World! WebGL 25 (VSCodeユーザ向け) 1個目のサンプル`src/sample1_hello_world_webgl/index.html` を右クリックして、Live Serverで開く
Hello World! WebGLの中身 26 1. (L6) html側で定義したcanvasのidを指定して、どのcanvasに描画するか決める 2. (L9) GLコンテキストと呼ばれる、描画命令を司るオブジェクトを作成。
この時に、引数に”webgl”ではなく、”webgl2”を指定。 3. (L23) 色を指定して、canvasをクリアする src/sample1_hello_world_webgl/hello_webgl.jsの解説 ID : webgl-canvas-id
Hello World! WebGLの中身 27 1. (L6) html側で定義したcanvasのidを指定して、どのcanvasに描画するか決める 2. (L9) GLコンテキストと呼ばれる、描画命令を司るオブジェクトを作成。
この時に、引数に”webgl”ではなく、”webgl2”を指定。 3. (L23) 色を指定して、canvasをクリアする src/sample1_hello_world_webgl/hello_webgl.jsの解説 GLコンテキスト
Hello World! WebGLの中身 28 1. (L6) html側で定義したcanvasのidを指定して、どのcanvasに描画するか決める 2. (L9) GLコンテキストと呼ばれる、描画命令を司るオブジェクトを作成。
この時に、引数に”webgl”ではなく、”webgl2”を指定。 3. (L20)(L23) 色を指定して、canvasをクリアする src/sample1_hello_world_webgl/hello_webgl.jsの解説
Hands-on① : 背景色を変更してみよう 29 canvasの背景色の色を、好きな色に変更しよう!
Hands-on①のヒント 30 rgba=(0.7, 0.7, 0.7, 1,0)で、canvasの色を塗り潰す。aは透明度。 (rgbの値は、0.0f~1.0fまでのfloatで指定。 描画される時に255倍されてuint8になる) ヒント:`src/sample1_hello_world_webgl/hello_webgl.js`のL23を修正 図引用:https://viewpoint-nk.github.io/blog/webgl/webgl-hello-world.html
Hands-on① : 背景色を変更してみよう 31 解答
シェーダーとは 32
2Dの正方形を描こう 33 サンプル2の実行結果(`src/sample2_2d_square/index.html`)
2Dの正方形を描こう 34 サンプル2のソースコード(src/sample2_2d_square/)を例に、解説!
シェーダーとは 35 図引用:https://fmiranda.me/courses/cs425-slides/04-webgl.pdf シーン(3D) (オブジェクト、マテリアル、カメラ、光源) 絵(2D) (レンダリング画像) レンダリ ング シェーダー
=実際に絵を描くとこを担当
シェーダーとは • シェーダーとは =GPU使って絵を描く人 • シェーダーにどのようにデータを渡すか? 36 シェーダー Javascript こんな感じの絵を
描いてくれ〜!
シェーダー2人いる! • シェーダー実はもう一人いる! 37 Javascript こんな感じの絵を 描いてくれ〜! シェーダー
2つのシェーダー 38 頂点シェーダー (=図形の頂点のみを描く人) フラグメントシェーダー (=ピクセルの色を塗る人) (0.3, 0.3) (-0.3, -0.3)
(0.3, -0.3) (-0.3, 0.3)
頂点シェーダー 39 頂点シェーダー (=図形の頂点のみを描く人) フラグメントシェーダー (=ピクセルの色を塗る人) (0.3, 0.3) (-0.3, -0.3)
(0.3, -0.3) (-0.3, 0.3)
頂点シェーダー 40 in:シェーダーの入力変数を表す修飾子。 out:シェーダーの出力変数を表す修飾子。 • 頂点シェーダーの2Dベクトル(vec2)の入力変数:`aVertexPosition`を宣言。 2Dの図形の頂点の座標を代入する。(例:[[0.3,0.3],[-0.3,0.3],...]) • `gl_Position`:出力変数。描画される頂点の座標(予約語なので、宣言しない) •
ベクトルが4D(vec4)なのは、3Dの同次座標系(n+1次元)のため。 (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) src/sample2_2d_square/shaders/vertex-shader-glsl.js
頂点シェーダー 41 • シェーダー部分は、GLSL(GL Shading Language)と呼ばれる 特有のシェーダー言語で書かれる。 ◦ GLSLの文法≠javascriptの文法 •
WebGL2で使われるシェーディング言語はGLSL。一方、厳密には、WebGL2 はOpenGLではなくOpenGL ES3.0の仕様に基づくので、GLSLのサブセット であるESSLと呼ぶのが正しいらしい。 (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) src/sample2_2d_square/shaders/vertex-shader-glsl.js
フラグメント シェーダー 42 頂点シェーダー (=図形の頂点のみを描く人) フラグメントシェーダー (=ピクセルの色を塗る人) (0.3, 0.3) (-0.3,
-0.3) (0.3, -0.3) (-0.3, 0.3)
フラグメント シェーダー 43 FlagColorという変数名の出力変数を宣言。 今回は、rgba=(0.5, 1, 1, 1)の固定色で、ピクセルの色を塗り潰す。 (rgbの値は、0.0f~1.0fまでのfloatで指定。 描画される時に255倍されてuint8になる)
src/sample2_2d_square/shaders/fragment-shader-glsl.js
2つのシェーダー 44 頂点シェーダー (=図形の頂点のみを描く人) フラグメントシェーダー (=ピクセルの色を塗る人) (0.3, 0.3) (-0.3, -0.3)
(0.3, -0.3) (-0.3, 0.3)
Hands-on② 2Dの正方形をいじろう 45
Hands-on② - 1:正方形の色を好きな色に変更してみよう! 46 src/sample2_2d_square/を修正して、 正方形の色を好きな色に変更してみよう!
Hands-on② - 1のヒント 47 頂点シェーダー (=図形の頂点のみを描く人) フラグメントシェーダー (=ピクセルの色を塗る人) (0.3, 0.3)
(-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) ピクセルの色を決めてたのは、、
Hands-on② - 1のヒント 48 ピクセルの色を決めてたのは、、 フラグメントシェーダー src/sample2_2d_square/shaders/fragment-shader-glsl.js
Hands-on② - 1:正方形の色を好きに変更してみよう! 49 解答 rgbの値を変更
レンダリング パイプライン 50
描画までの流れ 51 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル 3. シェーダーのリンク 4.
バッファの初期化 5. ドローコール main関数内
描画までの流れ 52 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール(描画命令) main関数内
描画までの流れ 53 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
描画までの流れ 54 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
シェーダーのコンパイル・リンクを行う関数を呼び出す 1. main.jsで、自作モジュール`init-shader.js`の 自作関数`initShaderProgram`をimport 2. main関数内で呼び出す 55
1. (L34)まずは、shaderオブジェクト (=シェーダーのスクリプトを読み込む用のオブジェクト)を作成。 2. (L37)次に、shaderオブジェクトにシェーダーのスクリプト(source)を読み込ませる。 3. (L40)shaderオブジェクトをコンパイル。 shaderオブジェクトの作成(コンパイル) 56 コンパイル中...
描画までの流れ 57 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
描画までの流れ 58 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
programオブジェクトの作成(リンク)① 59 1. (L9) programオブジェクト (=2つの両方のシェーダーの情報を保持する用のオブジェクト)を作成 2. (L12)作成したprogramオブジェクトに、 先程コンパイルした2つのシェーダー(shaderオブジェクト)を紐付ける。 program
オブジェクト
program オブジェクト 3. (L16) programオブジェクトを使って、2つのシェーダーのスクリプトをリンク。 4. (L25)programオブジェクトを、GLコンテキストに紐付ける。 (=使うことを教えてあげる) programオブジェクトの作成(リンク)② 60
リンク
描画までの流れ 61 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
描画までの流れ 62 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
バッファとは? • バッファとは? ◦ 広く一般的には、一時的に使われるメモリを指す。 • 一方、WebGLでは、 シェーダーが読み取るためのGPU上のメモリを指す。 63 バッファに格納された
頂点のデータを 使うぞ〜! 頂点シェーダー pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バッファ
1. main.jsで、自作モジュール`init-buffer.js`の自作関数`initBuffers`をimport 2. main関数内で呼び出す バッファの初期化を行う関数を呼び出す 64
1. (L51)空のバッファを作成(=GPU上のメモリ確保) 2. 作成したバッファに対して、 gl.ARRAY_BUFFERをバインド(=バッファの種類を、割り当てる) 3. 作成した空のバッファに、 頂点のデータ(例:positions=[0.3,0.3,...])を入れて、 バッファを埋める(=CPU側からGPU上のメモリに、データを転送して格納) バッファの初期化①
65 メモリ確保! (中身はまだない)
1. 空のバッファを作成(=GPU上のメモリ確保) 2. (L52)作成したバッファに対して、 gl.ARRAY_BUFFERをバインド(=バッファの種類を、割り当てる) 3. 作成した空のバッファに、 頂点のデータ(例:positions=[0.3,0.3,...])を入れて、 バッファを埋める(=CPU側からGPU上のメモリに、データを転送して格納) バッファの初期化②
66 このバッファは、頂点データだよ! シェーダー側で読み取っていいよ! バインド済み • gl.ARRAY_BUFFER =頂点データ(座標、色、法線など) • gl.ELEMENT_ARRAY_BUFFER =頂点の順番を表すデータ バッファの種類は2種類。
バッファの初期化③ • 頂点のデータの配列をCPU側で宣言(L46)。 67 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3
今回、GPU側に転送したい頂点のデータ。 変数宣言時には、VRAM上(CPU側)にある。 正方形の頂点の2D座標
1. 空のバッファを作成(=GPU上のメモリ確保) 2. 作成したバッファに対して、 gl.ARRAY_BUFFERをバインド(=バッファの種類を、割り当てる) 3. (L53)作成した空のバッファに、 頂点のデータ(例:positions=[0.3,0.3,...])を流し込んで、 バッファを埋める(=CPU側からGPU上のメモリに、データを転送して格納) バッファの初期化④
68 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バインド済み
1. (L51)空のバッファを作成(=GPU上のメモリ確保) 2. (L52)作成したバッファに対して、 gl.ARRAY_BUFFERをバインド(=バッファの種類を、割り当てる) 3. (L53)作成した空のバッファに、 頂点のデータ(例:positions=[0.3,0.3,...])を流し込んで、 バッファを埋める(=CPU側からGPU上のメモリに、データを転送して格納) バッファの初期化
69 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バインド済み
描画までの流れ 70 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール main関数内
描画までの流れ 71 1. ウェブページが読み込まれて、main.jsのmain関数が実行される (以下、main関数内) 2. シェーダーのコンパイル(shaderオブジェクトの作成) 3. シェーダーのリンク(programオブジェクトの作成) 4.
バッファの初期化(bufferオブジェクトの作成) 5. ドローコール(描画命令) main関数内
ドローコールを行う関数を呼び出す 1. main.jsで、自作モジュール`draw-scene.js`の 自作関数`drawScene`をimport 2. main関数内で呼び出す 72
バッファの初期化完了! 73 pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 頂点データが格納された GPU上のバッファ
バインド済み
頂点シェーダーはバッファに格納された値を使いたい 74 頂点シェーダー フラグメント シェーダー (0.3, 0.3) (-0.3, -0.3) (0.3,
-0.3) (-0.3, 0.3) pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バインド済み 頂点データが格納された GPU上のバッファ 頂点のデータ 使いたい〜!
頂点シェーダーはバッファに格納された値を使いたい 75 頂点シェーダー 頂点のデータ 使いたい〜! pos[0] =0.3 pos[1] =0.3 pos[2]
=-0.3 バインド済み 頂点データが格納された GPU上のバッファ
Attributeとは 76 頂点シェーダー 頂点のデータ 使いたい〜! pos[0] =0.3 pos[1] =0.3 pos[2]
=-0.3 バインド済み 頂点データが格納された GPU上のバッファ Attribute =頂点シェーダーの入力変数のこと 参考:WebGL2で、頂点シェーダー内での変数宣言の際の修飾子が、 attributeからinに変更。
Attributeのポインタでバッファを指し示す 77 頂点シェーダー 頂点のデータ 使いたい〜! pos[0] =0.3 pos[1] =0.3 pos[2]
=-0.3 バインド済み 頂点データが格納された GPU上のバッファ ポインタ Attribute =頂点シェーダーの入力変数のこと
Attributeのポインタでバッファを指し示す 78 頂点シェーダー pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バインド済み
頂点データ Attribute ポインタ バッファをAttributeのポインタで指し、頂点シェーダーに分かるように、バッファに 格納されたデータの説明をしてあげる どんな頂点の データなの〜? draw-scene.js(L10)
Attributeの有効化 79 頂点シェーダー pos[0] =0.3 pos[1] =0.3 pos[2] =-0.3 バインド済み
頂点データ Attribute ポインタ じゃあ使うね〜! Attributeを有効化 draw-scene.js(L11)
ビューポート変換とは 80 図引用:https://tokoik.github.io/gg/ggnote01.pdf ビューボリュームからはみ出たとこは描画しない (-1,-1,-1) (1,1,1) (0,0,0) ビューボリューム (クリッピング空間) draw-scene.js(L5)
ビューポート変換とは 81 gl.canvas.width gl.canvas.height (0, 0) ビューポート ビューボリューム内でシェーダーで描いた図形が、 ビューポート変換後、ビューポートがcanvasに表示される ビューポート変換
参考:WebGLとcanvasのサイズ (gl.canvas.width,gl.canvas.height) (-1,-1,-1) (1,1,1) (0,0,0) ビューボリューム (クリッピング空間) draw-scene.js(L5)
ビューポート変換による歪みを解消 82 ビューポート(canvas)のアスペクト比に 合わせて、頂点の座標を修正することで、 ビューポート変換の際の、図形の歪みを解消。 (長方形ではなく、正方形として表示される) 図引用 :https://mitani.cs.tsukuba.ac.jp/lecture/old2015/cg/03/03_slides.pdf init-buffer.js(L39)
ドローコール ドローコール(Draw call)=描画命令。 これでcanvas(描画領域)に描画される `gl.drawArrays()`の第一引数は、primitiveの種類。 今回の例では、`gl.TRIANGLE_STRIP`を指定。 =最初の3つの頂点が最初の三角形を形成し、その後は、 前の2つの頂点を再利用して、新たな1つの頂点が新しい三角形を形成。 83 図引用
:https://fmiranda.me/courses/cs425-slides/04-webgl.pdf draw-scene.js(L17)
Hands-on③ 三角形を描画してみよう 84
Hands-on② - 2:正方形→三角形を描画してみよう! 85 五角形や好きな図形でも!
Hands-on② - 2のヒント • 頂点の座標データ • ドローコール 86 今回、転送する頂点のデータ (正方形の2D座標)
Hands-on② - 2のヒント • 頂点の座標データ • ドローコール ◦ プリミティブのタイプ ◦
頂点の個数 87
Hands-on② - 2:正方形→三角形を描画してみよう! 88 • 頂点の座標データ • ドローコール ◦ プリミティブのタイプ
◦ 頂点の個数 解答
VBO, IBO and VAO 89
• バッファの種類3つ • VBO、IBO、VAO ◦ VBOとは? ▪ Vertex Buffer Object(頂点バッファオブジェクト)
◦ IBOとは? ▪ Index Buffer Object(インデックスバッファオブジェクト) ◦ VAOとは? ▪ Vertex Array Object 90 バッファの種類
VBO • VBOとは? ◦ Vertex Buffer Object(頂点バッファオブジェクト) • 頂点の座標、色、法線などの頂点のデータを表すバッファの名称。 91
(0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) 頂点の座標 VBO1つ 頂点の座標+色 VBO2つ 頂点の座標+色+法線 VBO3つ
IBO • IBOとは? ◦ Index Buffer Object(インデックスバッファオブジェクト) ◦ 頂点のインデックスの配列(描画の順番を表す。) •
同じ頂点データを使い回す時に有効。 92 • バインドするときにのバッファの種類を gl.ARRAY_BUFFERではなく、 gl.ELEMENT_ARRAY_BUFFER • ドローコールの際に、 gl.drawArrays()ではなく、gl.drawElements()
IBO使って、2Dの正方形を描こう 93 サンプル3の実行結果(`src/sample3_2d_square_ibo/index.html`)
VBO • VBOとは? ◦ Vertex Buffer Object(頂点バッファオブジェクト) • 頂点の座標、色、法線などの頂点のデータを表すバッファの名称。 94
(0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) (0.3, 0.3) (-0.3, -0.3) (0.3, -0.3) (-0.3, 0.3) 頂点の座標 VBO1つ 頂点の座標+色 VBO2つ 頂点の座標+色+法線 VBO3つ
複数のVBO • 頂点の座標+色+法線の場合、VBO3つ • VBO1つ1つバインドしたり、管理めんどくさい。一つに集約出来ないか...? 95 (0.3, 0.3) (-0.3, -0.3)
(0.3, -0.3) (-0.3, 0.3) 頂点の座標+色+法線 VBO3つ VBO (座標) VBO (色) VBO (法線)
VAO • 複数のVBOを、1つのVAOにまとめる。 • VAOは、attribute(頂点シェーダーの入力変数)のポインタを持ってる (ドローコールの際に、VAOをバインドするだけでOK) 96 VAO VBO (座標)
VBO (色) VBO (法線) ポインタ
VAOで、複数のVBOまとめる src/sample5_2d_square_vao_color 頂点の座標+色を、頂点シェーダーに入力。 97
Hands-on(optional) 3Dの立方体を描こう 98
3Dの立方体を描こう src/sample6_3d_cube 99
軌道(周回、Orbiting)カメラ src/sample11_3d_cube_orbit_cam_phongLight マウスのxy座標を読み取って、原点を中心にカメラが回転 100 図引用 :https://www.amazon.co.jp/GPU%E4%B8%A6%E5%88%97%E5%9B%B3% E5%BD%A2%E5%87%A6%E7%90%86%E5%85%A5%E9%96%80-CUDA% E3%83%BBOpenGL%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%A8 %E6%B4%BB%E7%94%A8-Software-Design-plus/dp/477416304X
複数の立方体の描画 src/sample12_3d_cube_orbit_cam_phong_pointLight_multipleCubes 立方体の数や落下・回転の速度を変えてみよう! 101
行列ライブラリ:glMatrix 102 図引用 :https://mitani.cs.tsukuba.ac.jp/lecture/old2015/cg/03/03_slides.pdf