プログラミング/JavaScript/three.js/再入門 のバックアップ差分(No.2)
更新- 追加された行はこの色です。
- 削除された行はこの色です。
[[公開メモ]] #contents * 準備 [#gf36364d] https://cdnjs.com/libraries/three.js へ行き、Copy Script Tag ボタン </> を押すと LANG:html <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" integrity="sha512-dLxUelApnYxpLt6K2iomGngnHO83iUvZytA3YjDUCjT0HDOHKXnVYdf3hU4JjM8uEhxf9nD1/ey98U3t2vZ0qQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> が手に入る。 そこでテスト用には、 LANG:html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <style> body { margin: 0; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" integrity="sha512-dLxUelApnYxpLt6K2iomGngnHO83iUvZytA3YjDUCjT0HDOHKXnVYdf3hU4JjM8uEhxf9nD1/ey98U3t2vZ0qQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> </head> <body> <!-- ここに html を書く --> <canvas id="canvas1" width="800", height="600"> <script> window.addEventListener("DOMContentLoaded", setup); function setup() { // ここにコードを書く } </script> </body> </html> のようなひな形を使えば良さそう。 * 立方体のチュートリアル [#c97f1541] ** レンダリングの基本 [#u21e2247] 公式チュートリアル:~ https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene 一部こちらも参考にさせていただいて:~ https://ics.media/entry/14771/ three.js で描画するには以下の手順を踏むことになる + 描画先を指定してレンダラーを作る + シーンを作る -- シーンにオブジェクトや光源を追加する + カメラを作る + シーンとカメラを指定してレンダリングする ここでは、 LANG:html <canvas id="canvas1" width="800", height="600"> に書き込むことにする。 LANG:js // ここにコードを書く // 描画先の canvas エレメント const canvas = document.querySelector("#canvas1"); // レンダラーを作成 (描画先を指定した) const renderer = new THREE.WebGLRenderer({canvas: canvas}); renderer.setSize( canvas.width, canvas.height ); renderer.setPixelRatio(window.devicePixelRatio); // カメラを作成 (画角、アスペクト比、描画開始距離、描画終了距離) const camera = new THREE.PerspectiveCamera( 45, canvas.width / canvas.height, 0.1, 10000 ); camera.position.set(0, 0, +1000); // x, y, z // シーンを作成 const scene = new THREE.Scene(); // ここでシーンにオブジェクトや光源を追加する // setup_scene(scene); // レンダリング renderer.render(scene, camera); これで正しくレンダリングされる。~ ただし、オブジェクトも光源もないシーンなので真っ暗なまま。 ** オブジェクトと光源を追加してみる [#z005ed48] LANG:js // ここでシーンにオブジェクトや光源を追加する setup_objects(scene); setup_lights(scene); function setup_lights(scene) { // 平行光源 const light = new THREE.DirectionalLight(0xff80ff); light.intensity = 1; light.position.set(1, 1, 1); scene.add(light); // シーンに追加 // 環境光 const ambient = new THREE.AmbientLight( 0x80ffff ); ambient.intensity = 0.2; scene.add(ambient); // シーンに追加 } function setup_objects(scene) { // 箱を作成 const geometry = new THREE.BoxGeometry(300, 300, 300); // 形状 const material = new THREE.MeshStandardMaterial({color: 0x8080ff}); // 単色の材質 const box = new THREE.Mesh(geometry, material); // 形状と材質を指定してメッシュを作成 box.rotation.x = 3.14/4; box.rotation.y = 3.14/4; scene.add(box); // シーンに追加 } これで立方体が表示された。 &ref(box1.png); ** アニメーションさせる [#s11c3846] 一定時間間隔でシーンを変更しつつ renderer.render を呼ぶための機構が備わっている。 LANG:js // レンダリング renderer.render(scene, camera); としていた部分を、 LANG:js function renderFrame() { renderer.render( scene, camera ); scene.update(); // シーンを更新する // 次フレームの描画を予約 requestAnimationFrame( renderFrame ); } // 次フレームの描画を予約 requestAnimationFrame( renderFrame ); とするとともに、オブジェクトの追加時に LANG:js function setup_objects(scene) { // 箱を作成 const geometry = new THREE.BoxGeometry(300, 300, 300); // 形状 const material = new THREE.MeshStandardMaterial({color: 0x8080ff}); // 単色の材質 const box = new THREE.Mesh(geometry, material); // 形状と材質を指定してメッシュを作成 box.rotation.x = 3.14/4; box.rotation.y = 3.14/4; scene.add(box); // シーンに追加 // シーンの更新方法を指定(箱を回転させる) scene.update = function() { box.rotation.x += 0.01; box.rotation.y += 0.01; } } のようにシーンの更新方法を登録しておく。 これでアニメーションが行われる。 &attachref(box1.gif); ** ここまでのコード [#bea92dc5] LANG:html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" integrity="sha512-dLxUelApnYxpLt6K2iomGngnHO83iUvZytA3YjDUCjT0HDOHKXnVYdf3hU4JjM8uEhxf9nD1/ey98U3t2vZ0qQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> </head> <body> <canvas id="canvas1" width="800", height="600"></canvas> <script> window.addEventListener("DOMContentLoaded", init); function init() { // 描画先の canvas エレメント const canvas = document.querySelector("#canvas1"); // レンダラーを作成 (描画先を指定した) const renderer = new THREE.WebGLRenderer({canvas: canvas}); renderer.setSize( canvas.width, canvas.height ); renderer.setPixelRatio(window.devicePixelRatio); // カメラを作成 (画角、アスペクト比、描画開始距離、描画終了距離) const camera = new THREE.PerspectiveCamera( 45, canvas.width / canvas.height, 0.1, 10000 ); camera.position.set(0, 0, +1000); // x, y, z // シーンを作成 const scene = new THREE.Scene(); // ここでシーンにオブジェクトや光源を追加する setup_objects(scene); setup_lights(scene); // レンダリング renderer.render(scene, camera); function renderFrame() { renderer.render( scene, camera ); scene.update(); // シーンを更新する // 次フレームの描画を予約 requestAnimationFrame( renderFrame ); } // 次フレームの描画を予約 requestAnimationFrame( renderFrame ); } function setup_lights(scene) { // 平行光源 const light = new THREE.DirectionalLight(0xff80ff); light.intensity = 1; light.position.set(1, 1, 1); scene.add(light); // シーンに追加 // 環境光 const ambientLight = new THREE.AmbientLight( 0x80ffff ); ambientLight.intensity = 0.2; scene.add( ambientLight ); } function setup_objects(scene) { // 箱を作成 const geometry = new THREE.BoxGeometry(300, 300, 300); // 形状 const material = new THREE.MeshStandardMaterial({color: 0x8080ff}); // 単色の材質 const box = new THREE.Mesh(geometry, material); // 形状と材質を指定してメッシュを作成 box.rotation.x = 3.14/4; box.rotation.y = 3.14/4; scene.add(box); // シーンに追加 // シーンを更新する(箱を回転させる) scene.update = function() { box.rotation.x += 0.01; box.rotation.y += 0.01; } } </script> </body> </html> のようなひな形を使えば良さそう。 * 任意形状のメッシュを生成 [#k98c0e43] LANG:js function setup_objects(scene) { // 正方形の頂点セット // 実際には2つの三角形を組み合わせて正方形にしているため // (0,0,0) と (100,100,0) が2回表れる const vertices = new Float32Array( [ 0, 0, 0, 100, 0, 0, 100, 100, 0, 100, 100, 0, 0, 100, 0, 0, 0, 0, ] ); const geometry = new THREE.BufferGeometry(); // 頂点あたりの引数の数を itemSize = 3 として指定 geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); geometry.computeVertexNormals(); // これを忘れると表示されない const material = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); material.side = THREE.DoubleSide; // 裏側も描画 const mesh = new THREE.Mesh( geometry, material ); scene.add(mesh); // シーンを更新する(箱を回転させる) scene.update = function() { mesh.rotation.x += 0.01; mesh.rotation.y += 0.02; mesh.rotation.z += 0.005; } } &attachref(square1.gif); * ExtrudeGeometry で厚みのある形状 [#u23e7cb1] https://threejs.org/docs/#api/en/geometries/ExtrudeGeometry LANG:js function setup_objects(scene) { const h = 120, w = 80; const shape = new THREE.Shape(); shape.moveTo( 0,0 ); shape.lineTo( 0, w ); shape.lineTo( h, w ); shape.lineTo( h, 0 ); shape.lineTo( 0, 0 ); const extrudeSettings = { steps: 2, // 押し出し方向の分割数 depth: 160, // 押し出し長さ bevelEnabled: true, bevelThickness: 30, // 押し出し方向 bevelSize: 30, // 面内方向 bevelOffset: 20, // 外形からの距離(って何だ?) bevelSegments: 1 // 大きくすると丸くなる }; const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings ); geometry.computeVertexNormals(); // これを忘れると表示されない const material = new THREE.MeshStandardMaterial( { color: 0xffffff } ); material.side = THREE.DoubleSide; // 裏側も描画 const mesh = new THREE.Mesh( geometry, material ); scene.add(mesh); // シーンを更新する(箱を回転させる) scene.update = function() { mesh.rotation.x += 0.01; mesh.rotation.y += 0.02; mesh.rotation.z += 0.005; } } 右は bevelSegments = 10 としたもの。 &attachref(extruded1.gif,,66%); &attachref(extruded2.gif,,66%);
Counter: 4949 (from 2010/06/03),
today: 5,
yesterday: 0