Mais conteúdo relacionado Semelhante a 3DCG(3Dコンピュータグラフィック)をWebGLで始めよう (20) Mais de AdvancedTechNight (18) 3DCG(3Dコンピュータグラフィック)をWebGLで始めよう1. Advanced Tech Night No.7
3DCG (3Dコンピュータグラフィック)を
WebGLで始めよう!
2013/08/30
Acroquest Technology 株式会社
秋葉 誠
2. 自己紹介
秋葉 誠 (@mac_akiba)
公共向け集中監視システム
フレームワーク開発やってました
バックエンド系中心
現在はインフラ系のお仕事
・Linux
・PostgreSQL
・Hadoop
など
Advanced Tech Night
1
久しぶりに、
フロントエンド系の
技術を触ってみました。
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. 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. 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. 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;
}
};
ちょっとした図形を書くだけなのに、
こんなにコードを書かなければならないなんて...
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. // 光源を生成
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);
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. 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のアニメーション機構)
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. 3.WebGLを使う場合の注意点
2. 機能上の制限
① 凸角形しか作れない。裏表がある
a. Canvasのように凹角形のデータは作れない。
Three.jsでも同様。
b. 凹角形や、中空のモデルを表示するためには、
面分割をしてくれる補助ライブラリ(→後述)が必要。
② Three.jsは楽だが、細かい調整は苦手
a. 提供されているモデルを変形させられないため、
凝ったモデルを表示するには別途頂点データが必要。
→変形させたモデルでも、モデルローダーを使うことに
③ デバッグが大変
Advanced Tech Night
21
30. Copyright © Acroquest Technology Co., Ltd. All rights reserved.
29
ご清聴有難うございました。
Infrastructures Evolution