Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

3DCG(3Dコンピュータグラフィック)をWebGLで始めよう

4,908 views

Published on

Published in: Technology
  • Be the first to comment

3DCG(3Dコンピュータグラフィック)をWebGLで始めよう

  1. 1. Advanced Tech Night No.7 3DCG (3Dコンピュータグラフィック)を WebGLで始めよう! 2013/08/30 Acroquest Technology 株式会社 秋葉 誠
  2. 2. 自己紹介  秋葉 誠 (@mac_akiba)  公共向け集中監視システム フレームワーク開発やってました  バックエンド系中心 現在はインフラ系のお仕事 ・Linux ・PostgreSQL ・Hadoop など Advanced Tech Night 1 久しぶりに、 フロントエンド系の 技術を触ってみました。
  3. 3. 発表内容! 1. WebGLとは? 2. WebGLを使ってみよう 3. WebGLを使う場合の注意点 4. ライブラリの紹介 5. まとめ Advanced Tech Night 2
  4. 4. 1.WebGLとは? Advanced Tech Night No.7 3DCGをWebGLで始めよう! Advanced Tech Night 3
  5. 5. 1-1.WebGLとは? 1. WebGLはWeb( JavaScript )用 のOpenGL ES 2.0(※)ライブラリ (※)OpenGL ES: OpenGLの組み込み版 ① JavaScriptからOpenGL ES 2.0を呼び出すブリッジAPI →対応ブラウザならば、プラグイン無しに、ブラウザ上で高速に 3D表示ができる。 ② グラフィックスカードがOpenGLに対応している必要あり。 2. WebGLが生まれた経緯 ① 最初は、MozillaがCanvas3Dの実験を開始。 ② 2009年に、Khronos(クロノス)グループがWebGLワーキンググループ を発足。 ③ 2011年に、WebGL1.0が仕様化。 ④ 2013/08現在、Version1.0.2が最新。 Advanced Tech Night 4
  6. 6. 1-2.WebGLは高速/高機能だが実装が大変 Advanced Tech Night 5 1. OpenGL ES2をJavaScriptに落とし込んでいる →同じ機能が使える(=高機能)、GPUを使った高速描画 WebGL Canvas SVG Flash 高速描画 ◎ △ ライブラリ/ オブジェクト数による × ○ 3D描画機能 ◎ △ △ ○ 実装の簡単さ × × △ ○ オーサリングツールが 必要 DOMイベント × ○ △ ○ DOMではないが イベントの作成に対応 文字列描画 × △ 埋込みフォント未対応 ○ ○ 互換性 × 今後増えるかも? △ IE以外はだいたいOK ○ △ モバイルでは動かない けど、安くない... (実装が面倒) 美味い! (OpenGL ES2の機能そのまま) 速い! (GPUで高速描画)
  7. 7. 1-2.WebGLは高速/高機能だが実装が大変 2. WebGLだけだと、どんだけ大変?  簡単な三角形(平面)を書くなんだけど… Advanced Tech Night 6 onload = function() { // canvasエレメントを取得 var c = document.getElementById('canvas'); c.width = 500; c.height = 500; var gl = c.getContext('webgl') || c.getContext('experimental-webgl'); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // 頂点シェーダとフラグメントシェーダの生成 var v_shader = create_shader('vs'); var f_shader = create_shader('fs'); var prg = create_program(v_shader, f_shader); var attLocation = gl.getAttribLocation(prg, 'position'); var attStride = 3; // モデルデータ(頂点座標) var vertex_position = [ 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0 ]; // VBOの生成 var vbo = create_vbo(vertex_position); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); gl.enableVertexAttribArray(attLocation); gl.vertexAttribPointer(attLocation, attStride, gl.FLOAT, false, 0, 0); 次頁に続く→ polygon.js (1/2)表示結果
  8. 8. 1-2.WebGLは高速/高機能だが実装が大変 Advanced Tech Night 7 // minMatrix.js を用いた行列関連処理 // matIVオブジェクトを生成 var m = new matIV(); var mMatrix = m.identity(m.create()); var vMatrix = m.identity(m.create()); var pMatrix = m.identity(m.create()); var mvpMatrix = m.identity(m.create()); m.lookAt([0, 0, 1.5], [0, 0, 0], [0, 1, 0], vMatrix); m.perspective(90, c.width / c.height, 0.1, 100, pMatrix); m.multiply(pMatrix, vMatrix, mvpMatrix); m.multiply(mvpMatrix, mMatrix, mvpMatrix); var uniLocation = gl.getUniformLocation(prg, 'mvpMatrix'); gl.uniformMatrix4fv(uniLocation, false, mvpMatrix); // モデルの描画 gl.drawArrays(gl.TRIANGLES, 0, 3); gl.flush(); // シェーダを生成する関数 function create_shader(id) { var shader; var scriptElement = document.getElementById(id); if (!scriptElement){ return; } switch(scriptElement.type){ case 'x-shader/x-vertex': shader = gl.createShader(gl.VERTEX_SHADER); break; case 'x-shader/x-fragment': shader = gl.createShader(gl.FRAGMENT_SHADER); break; default : return; } gl.shaderSource(shader, scriptElement.text); gl.compileShader(shader); polygon.js (2/2) JavaScriptのコード行数: →100行 if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { return shader; } else { alert(gl.getShaderInfoLog(shader)); } } // プログラムオブジェクトを生成しシェーダをリンクする関数 function create_program(vs, fs){ var program = gl.createProgram(); gl.attachShader(program, vs); gl.attachShader(program, fs); gl.linkProgram(program); if (gl.getProgramParameter(program, gl.LINK_STATUS)) { gl.useProgram(program); return program; } else { alert(gl.getProgramInfoLog(program)); } } // VBOを生成する関数 function create_vbo(data){ var vbo = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, null); return vbo; } }; ちょっとした図形を書くだけなのに、 こんなにコードを書かなければならないなんて...
  9. 9. 1-2.WebGLは高速/高機能だが実装が大変 3. OpenGL/WebGLの3D独特な概念は理解が難しい (頂点配列、シェーダー、視錐体…??) Advanced Tech Night 8 補助ライブラリを使うべし
  10. 10. 1-3.Three.jsで、WebGLを使う  Three.js ① Three.jsはWebGLの冗長な仕様をうまくラップし、 扱いやすいインターフェイスで提供するライブラリ。 ② Mr.Doob氏を中心にオープンソースで開発が進め られており、WebGL界隈ではデファクトスタンダー ドに近い地位を築いている。 ③ WebGL非サポート環境用としてCanvasやSVGで のレンダリングも可能で、WebGLまたはWebでの 3D表現の入門用にはうってつけのライブラリとい える。 Advanced Tech Night 9 http://mrdoob.github.io/three.js/
  11. 11. 2.Three.jsでWebGLを使ってみよう Advanced Tech Night No.7 3DCGをWebGLで始めよう! Advanced Tech Night 10
  12. 12. 2-1.Three.jsでポリゴンを描画してみる Advanced Tech Night 11 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>WebGL polygon sample (three.js)</title> <style type="text/css"> div#canvas-frame{ border: none; cursor: pointer; width: 600px; height: 600px; background-color: #EEEEEE; } </style> <script src="three.min.js"></script> <script src="polygon_three.js"></script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body> </html> JavaScriptを読み込む Canvasを用意して、ロード時に スクリプトを実行する polygon_three.html 600x600 pxのCanvasを作る
  13. 13. // 光源を生成 light = new THREE.DirectionalLight(0xFF0000, 1.0, 0); light.position.set(100, 100, 200); scene.add(light); } // オブジェクトを生成する function initObject(){ plane = new THREE.Mesh( new THREE.PlaneGeometry(50,50,1,2), new THREE.MeshLambertMaterial({color: 0xff0000}) ); scene.add(plane); plane.position.set(0,0,0); } // 描画をスタートする function threeStart() { initThree(); initObject(); renderer.clear(); renderer.render(scene, camera); } 2-1.Three.jsでポリゴンを描画してみる Advanced Tech Night 12 polygon_three.js 平面を指定するGeometry JavaScriptのコード行数: → 48行 HTMLのonloadで実行される var renderer; var camera; var scene; var light; var ambient; var plane; // Three.jsを初期化し、カメラ、シーン、光源を準備する function initThree() { // Three.jsを初期化 width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById(‘canvas-frame’).clientHeight; renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(width, height); document.getElementById(‘canvas-frame’) .appendChild(renderer.domElement); renderer.setClearColorHex(0xcccccc, 1.0); // シーンを生成 scene = new THREE.Scene(); // カメラを生成 camera = new THREE.PerspectiveCamera(45,width/height,1,10000); camera.position.x = 100; camera.position.y = 20; camera.position.z = 50; camera.up.x = 0; camera.up.y = 0; camera.up.z = 1; camera.lookAt({x:0, y:0, z:0}); scene.add(camera);
  14. 14. 2-1.Three.jsでポリゴンを描画してみる Advanced Tech Night 13 こんな感じになりました。
  15. 15. 2-2.立方体を書いて、ぐるぐる回してみる Advanced Tech Night 14 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>WebGL cube sample (three.js)</title> <style type="text/css"> div#canvas-frame{ border: none; cursor: pointer; width: 600px; height: 600px; background-color: #EEEEEE; } </style> <script src="three.min.js"></script> <script src=“cube_three.js"></script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body> </html> JavaScriptを読み込む (名前変えただけ) cube_three.html
  16. 16. 2-2.立方体を書いて、ぐるぐる回してみる Advanced Tech Night 15 cube_three.js 図形の変更はGeometryの 種類を変えるだけ var renderer; var camera; var scene; var light; var ambient; var cube; var baseTime; // Three.jsを初期化し、カメラ、シーン、光源を準備する function initThree() { // Three.jsを初期化 width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById(‘canvas-frame’).clientHeight; renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(width, height); document.getElementById(‘canvas-frame’) .appendChild(renderer.domElement); renderer.setClearColorHex(0xcccccc, 1.0); // シーンを生成 scene = new THREE.Scene(); // カメラを生成 camera = new THREE.PerspectiveCamera(45,width/height,1,10000); camera.position.x = 100; camera.position.y = 20; camera.position.z = 50; camera.up.x = 0; camera.up.y = 0; camera.up.z = 1; camera.lookAt({x:0, y:0, z:0}); scene.add(camera); // 光源を生成 light = new THREE.DirectionalLight(0xFF0000, 1.0, 0); light.position.set(100, 100, 200); scene.add(light); ambient = new THREE.AmbientLight(0x663333); ambient.position.set(100, 100, 200); scene.add(ambient); } // オブジェクトを生成する function initObject() { cube = new THREE.Mesh( new THREE.CubeGeometry(50,50,50), new THREE.MeshLambertMaterial({color: 0xff0000}) ); scene.add(cube); plane.position.set(0,0,0); } function render() { requestAnimationFrame(render); renderer.render(scene, camera); cube.rotation.y = 0.3 * (+new Date - baseTime) / 1000; cube.rotation.z = 0.3 * (+new Date - baseTime) / 1000; renderer.render(scene, camera); }; // 描画をスタートする function threeStart() { initThree(); initObject(); renderer.clear(); baseTime = +new Date; render(); } こっち半分は、 ポリゴンと一緒 立方体/長方体に変更 →クラスを変えるだけ グルグル回転させる (JavaScriptのアニメーション機構)
  17. 17. 2-2.立方体を書いて、ぐるぐる回してみる こんな感じになりました。(動かしてみましょう) Advanced Tech Night 16
  18. 18. 2-3.ここまでのまとめ! Three.jsを使ってWebGL 3D表示を始めるには Advanced Tech Night 17 1.Three.jsを初期化する! 2.シーンを生成する! 3.カメラを生成する! 4.光源を生成する! 5.オブジェクトを生成する! あとは、 好きなだけ グリグリ しちゃって ください 6.レンダラで描画する!
  19. 19. 世の中にある demoを 見てみよう Advanced Tech Night 18
  20. 20. 3.WebGLを使う場合の注意点 Advanced Tech Night No.7 3DCGをWebGLで始めよう! Advanced Tech Night 19
  21. 21. 3.WebGLを使う場合の注意点 1. 環境上の制限 ① ブラウザのサポート状況(PC) • デスクトップではほぼサポート/IEは11でようやく • ただし、ビデオカードでOpenGL2.0の対応が必要 ② ブラウザのサポート状況(Android/iPhone) • Androidは動くけれど設定変更必要+やはり遅い • iOS(Safari)はごめんなさい Advanced Tech Night 20 ブラウザ IE FireFox Chrome Opera Safari サポート 11~ 4~ 8~ (9から標準) 12~ (15から標準) 5.1~ ブラウザ - FireFox Chrome Opera Safari(iOS) サポート - 4~ 25~ 12~ (15から標準) ×
  22. 22. 3.WebGLを使う場合の注意点 2. 機能上の制限 ① 凸角形しか作れない。裏表がある a. Canvasのように凹角形のデータは作れない。 Three.jsでも同様。 b. 凹角形や、中空のモデルを表示するためには、 面分割をしてくれる補助ライブラリ(→後述)が必要。 ② Three.jsは楽だが、細かい調整は苦手 a. 提供されているモデルを変形させられないため、 凝ったモデルを表示するには別途頂点データが必要。 →変形させたモデルでも、モデルローダーを使うことに ③ デバッグが大変 Advanced Tech Night 21
  23. 23. 3.WebGLを使う場合の注意点 3. 実装上の注意 ① JavaScriptに極力処理させない グラフィックカードの処理の方が圧倒的に早い。 →グラフィックカードにできるだけ処理を任せる。 ② データをなるべく転送しない 遅さにつながるWebGLでの暗黙の変換。 →ビデオカードも大きなメモリを持っているので、 極力メモリ上で管理する。 Advanced Tech Night 22
  24. 24. 4.ライブラリの紹介 Advanced Tech Night No.7 3DCGをWebGLで始めよう! Advanced Tech Night 23
  25. 25. 4.ライブラリの紹介 1. Three.js → 前述のとおり 2. subdivision関連 3. シェーディング周り 4. モデルローダー Advanced Tech Night 24
  26. 26. 4.ライブラリの紹介 2. subdivision関連 ① 前述のとおり、WebGLでは凹角形や中空の モデルは作れない。ではどうするか? →凹角形のモデルを、細かい三角形 (必ず凸になる)のポリゴンに分割 する(=subdivisioning) ② 有名なsubdivisionライブラリ • poly2tri Advanced Tech Night 25 https://code.google.com/p/poly2tri/ 凹角形 中空
  27. 27. 4.ライブラリの紹介 3. シェーディングライブラリ ① WebGLはデフォルトのシェーダーを持たない。 →Three.jsは代表的なシェーダーを提供している が、複雑なシェーディングを行おうとすると、 独自のシェーダーが必要となる。 →イチからシェーダーを定義せずに、ライブラリを 使うのが楽。 ② 有名なシェーディングライブラリ • GLOW Advanced Tech Night 26 http://i-am-glow.com/
  28. 28. 4.ライブラリの紹介 4. モデルローダー ① 3Dモデリングソフトなどで作った頂点データを WebGL/three.jsに読み込むためのローダー。 ② 有名なモデルローダー • webgl-loader Advanced Tech Night 27 https://code.google.com/p/webgl-loader/
  29. 29. 5.まとめ 1.WebGLを使うことで、ブラウザ上で 高速な3D描画を実現できる。 2.生で使うには実装が煩雑。Three.js など、補助ライブラリを活用しよう。 3.3Dだからこそできる表現を、簡単に 実現してインタラクティブなUXを! Advanced Tech Night 28
  30. 30. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 29 ご清聴有難うございました。 Infrastructures Evolution

×