Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WebGL2 ノウハウ・Tips集

WebGL2 ノウハウ・Tips集

Yuki Shimada

May 07, 2022
Tweet

More Decks by Yuki Shimada

Other Decks in Programming

Transcript

  1. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGLとは ★ Webブラウザー向けの3Dグラフィックス JavaScript API

    ★ HTMLのcanvasに3Dグラフィックスを表示する ★ OpenGLがベースのため、経験者は対応しやすい ★ Web標準であるため末永いサポートが期待できる WebGL and the WebGL logo are trademarks of the Khronos Group Inc.
  2. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL 1.0 ★ OpenGL ES

    2.0(2007年リリース)相当の機能性 ◦ シェーダープログラムを送って実行させることで GPUに任意の処理をさせられる ▪ 頂点シェーダー (頂点単位の処理) ▪ フラグメントシェーダー (ピクセル単位の処理) ◦ 動的ループや変数の型などはまだ制約が多い ★ オプションとして拡張機能が定義されている 拡張機能により WebGL 2に近い機能性を得られるブラウザが多く、 開発者はそれらを活用して高い表現を実現する。 ◦ 主な拡張機能 ▪ ANGLE_instanced_arrays (一つの命令でたくさん描画 ) ▪ OES_texture_float_linear (浮動小数点テクスチャ ) ▪ WEBGL_draw_buffers (一度に複数先にレンダリング ) ▪ OES_standard_derivatives (シェーダーで微分値を得てより高度な表現を実現 ) WebGL Water Simulation By Evan Wallace https://experiments.withgoogle.com/webgl -water-simulation WebGL Aquarium By Human Engines and Gregg Tavares http://webglsamples.org/aquarium/aquarium.html
  3. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL 2.0 ★ 機能が大きく強化・改善 ◦

    OpenGL ES 3.0(2012年リリース) と同等 ◦ シェーダーで動的ループやビット演算のサポート ◦ 3Dテクスチャのサポート ◦ WebGL 1で拡張扱いだった機能の大半を標準サポート ◦ 本格的なアンチエイリアシング( MSAA)が可能に ◦ VR高速化のための拡張機能をサポートするブラウザも ★ APIの機能性はPS3/Xbox360世代に近い ★ 2021年、対応が遅れていたiOSとmacOSの SafariもついにWebGL2を標準サポート ★ 普及によりWeb3Dの表現の底上げが期待される After the Flood By PlayCanvas and Mozilla 用語 アンチエイリアシング  3D画像のギザギザ感を低減する手法のこと MSAA  アンチエイリアシングの手法のひとつ
  4. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP Web3D関連 APIのこれから ★ WebGL1はこれからも引き続きサポートされる( Web標準であるため)

    WebGL2は今後しばらくWeb3D表現の新たなベースラインに? ★ WebGL(OpenGL系)APIの制約を受けずに 性能・機能をより向上させるための 新しいWeb3D API WebGPU が策定中。 WebGPUは2022年以降各種ブラウザで利用可能になる見込み ★ Web向けAR/VR等をサポートする API WebXR 各種VRデバイスやARデバイス、スマートフォンなどがサポート Webでどこまでリッチな3 D体験ができるか、今後の進化が期待される WebGL and the WebGL logo are trademarks of the Khronos Group Inc. GPU for the Web Working Group of W3C Immersive Web Working Group of W3C
  5. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGLの情報ソース Khronos WebGL page: https://www.khronos.org/webgl/

    WebGLを策定している Khronos GroupのWebサイト。 WebGL仕様のページや Githubリポジトリ、Conformance(互換性)テストなどの重要な情報 へのリンクが多数。 MDN WebGL page: https://developer.mozilla.org/ja/docs/Web/API/WebGL_API Mozillaが運営する開発者向け Web技術ページ MDNのWebGLコーナー。 WebGL APIの詳細な説明、使い方の例などが豊富。
  6. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL 1 & 2 Quick

    Reference Guide WebGL1、WebGL2の関数や型、WebGLオブジェクトなどの仕様を一覧 できるクイックリファレンス資料がダウンロードできます。
  7. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL Conformance Test Test実行ページ: https://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html

    ブラウザ上でWebGL規格適合性テストを実際に試すことができます(注意:オプションの数によってはブラウザが固まる/クラッシュ等の危険があります)
  8. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP HTML Canvas要素 ラスターグラフィックスを描画するための HTML要素 JavaScript制御で画像を自由にプログラム描画できる

    const canvas = document .querySelector ('canvas' ); const context = canvas .getContext ('webgpu' ); const adapter = await navigator.gpu. requestAdapter (); const device = await adapter. requestDevice (); const presentationFormat = context. getPreferredFormat (adapter); context.configure({ device, format: presentationFormat,  size: [800, 600] }); …… const canvas = document .querySelector ('canvas' ); const gl = canvas .getContext ('webgl'); gl.clearColor(0, 1, 0, 1 ); gl.clear(gl .COLOR_BUFFER_BIT ); 3Dグラフィックス const canvas = document .querySelector ('canvas' ); const ctx = canvas .getContext ('2d'); ctx.fillStyle = 'green'; ctx.fillRect (10, 10, 100, 100); 2Dグラフィックス WebGL1 WebGPU <canvas width="800" height="600"> </canvas> 新しいWeb3D APIであるWebGPUもcanvasを使って描画する。 (描画結果がラスターグラフィックスになる APIは今後もcanvas??) ※ラスターグラフィックス:ピクセル(画素)ベースの画像のこと Canvasは内部にピクセルデータ領域を持っており、     描画の仕組みは独立して(複数)持てる設計 利用したい方式のコンテキストをCanvasから取得する (現在は 2D, WebGL1, WebGL2, WebGPU) const canvas = document .querySelector ('canvas' ); const gl = canvas .getContext ('webgl2' ); gl.clearColor(0, 1, 0, 1 ); gl.clear(gl .COLOR_BUFFER_BIT ); WebGL2
  9. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP CanvasとVRは関係ある? Webブラウザの3D表示においてCanvasは不可欠 → WebのVRでは? WebVR時代(WebXRの前進となった旧規格)

    canvasをWebVR APIのオブジェクトにセットする https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestPresent WebXRでは WebXRのセッションの子孫が持つ WebGLFrameBufferを 直接WebGLに指定する方式 https://developer.mozilla.org/en-US/docs/Web/API/XRWebGLLayer/framebuffer VRでは表示のターゲットは Webブラウザではなく、 VR機器のネイティブ機構そのもの。 Webブラウザ上の描画結果を VR機器側に転送することになる。 受け渡し方はそのAPIの仕様次第。 (Webブラウザ側のCanvasとVR機器の両方に3D表示をさせること も可能)
  10. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL2ではgl.texImage2Dより gl.texStorage2Dを使おう① gl.texImage2Dでは描画時に内部フォーマットの一貫性チェックが入ってしまう。 gl.texStorage2Dでは初回設定で固定されチェック不要となり描画負荷が軽くなる。 void

    gl.texStorage2D(target, levels, internalformat, width, height); target: gl.TEXTURE_2Dまたはgl.TEXTURE_CUBE_MAP levels: ミップマップレベルの数 internalformat: 内部フォーマットの種類を指定。 width: テクスチャの(一番大きいミップマップレベルの)横ピクセル幅 height: テクスチャの(一番大きいミップマップレベルの)縦ピクセル幅 詳しくはMDN(https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texStorage2D)を参照 引数の説明
  11. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL2ではgl.texImage2Dより gl.texStorage2Dを使おう② GL_TEXTURE_2Dの場合 for (i

    = 0; i < levels; i++) // 全てのミップマップレベルで { // サイズと内部フォーマットのみを指定する glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL); width = max(1, (width / 2)); // 次のループに備えて次のミップマップレベルのwidth(半分のサイズ)を計算 height = max(1, (height / 2)); // 次のループに備えて次のミップマップレベルのheight(半分のサイズ)を計算 } GL_TEXTURE_CUBE_MAPの場合 for (i = 0; i < levels; i++) // 全てのミップマップレベルで { for (face in (+X, -X, +Y, -Y, +Z, -Z)) // 各面ごとに { // サイズと内部フォーマットのみを指定する glTexImage2D(face, i, internalformat, width, height, 0, format, type, NULL); } width = max(1, (width / 2)); // 次のループに備えて次のミップマップレベルのwidth(半分のサイズ)を計算 height = max(1, (height / 2)); // 次のループに備えて次のミップマップレベルのheight(半分のサイズ)を計算 } 行われる処理としてはgl.texImage2Dで以下の処理を実行したのと同じ。 gl.texImage2Dでの通常のやり方と異なり、この関数では内部フォーマットと サイズを指定しただけ。実際のピクセルデータは別途送る必要があります。
  12. https://twitter.com/i/communities/1509011612589510657 https://cg-rnd.growi.cloud/webgl Twitter Hash: #Web3D_LP WebGL2ではgl.texImage2Dより gl.texStorage2Dを使おう③ const tex =

    gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); gl.texStorage2D(gl.TEXTURE_2D, 6, internalFormat.index, 64, 64); gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64 gl.RGBA, gl.UNSIGNED_BYTE, data[0]); if (generateMipmap) { gl.generateMipmap(gl.TEXTURE_2D); } else { gl.texSubImage2D(gl.TEXTURE_2D, 1, 0, 0, 32, 32, gl.RGBA, gl.UNSIGNED_BYTE, data[1]); gl.texSubImage2D(gl.TEXTURE_2D, 2, 0, 0, 16, 16, gl.RGBA, gl.UNSIGNED_BYTE, data[2]); gl.texSubImage2D(gl.TEXTURE_2D, 3, 0, 0, 8, 8, gl.RGBA, gl.UNSIGNED_BYTE, data[3]); gl.texSubImage2D(gl.TEXTURE_2D, 4, 0, 0, 4, 4 gl.RGBA, gl.UNSIGNED_BYTE, data[4]); gl.texSubImage2D(gl.TEXTURE_2D, 5, 0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data[5]); gl.texSubImage2D(gl.TEXTURE_2D, 6, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, data[6]); } gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS.index); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT.index); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter.index); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter.index); gl.bindTexture2D(null); gl.texStorage2Dでサイズと内部フォーマットを指定した後は、 gl.texSubImage2Dを使って実際のテクスチャのピクセルデータを転送できます。 詳しくはMDN(https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texSubImage2D)を参照