お世話になります。
大量に作成したパーティクルを読み込んだ3Dモデルの頂点座標に配置したいのですが、以下の2点で問題があります。
①object.scale.set();、object.rotation.set();で変更した大きさ、傾きの通りに頂点座標を更新したい
②頂点座標が密集していた場合、パーティクル間の隙間を空けたい
①はverticesNeedUpdate等をやってみたのですが変わりませんでした。他にやり方があるのでしょうか?
②は表示モデルの大きさ次第になると思いますが、どのような方法がありますでしょうか?
ご教示の程よろしくお願い致します
lang
1<html> 2 3<head> 4 <meta charset="utf-8" /> 5 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script> 6 <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.1/TweenMax.min.js"></script> 7 <script src="js/OrbitControls.js"></script> 8 <script src="js/TDSLoader.js"></script> 9 10 <script> 11 // ページの読み込みを待つ 12 window.addEventListener('load', init); 13 14 function init() { 15 // サイズを指定 16 const width = innerWidth; 17 const height = innerHeight; 18 let rot = 0; // 角度 19 // レンダラーを作成 20 const renderer = new THREE.WebGLRenderer({ 21 canvas: document.querySelector('#myCanvas'), 22 }); 23 renderer.setPixelRatio(window.devicePixelRatio); 24 renderer.setSize(width, height); 25 // シーンを作成 26 const scene = new THREE.Scene(); 27 // カメラを作成 28 const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000); 29 // カメラの初期座標を設定 30 camera.position.set(0, 0, 5); 31 // カメラコントローラーを作成 32 const controls = new THREE.OrbitControls(camera); 33 // 平行光源を作成 34 const directionalLight = new THREE.DirectionalLight(0xFFFFFF); 35 directionalLight.position.set(1, 1, 1); 36 scene.add(directionalLight); 37 // 環境光を追加 38 const ambientLight = new THREE.AmbientLight(0xFFFFFF); 39 scene.add(ambientLight); 40 41 const eggGeometry = new THREE.Geometry(); 42 const loader = new THREE.TDSLoader(); 43 loader.setPath('imgs/'); 44 loader.load('js/egg.3ds', (object) => { 45 if (object) { 46 let eggVerticesArray = object.children[0].geometry.attributes.position.array; 47 for (let i = 0; i < eggVerticesArray.length; i+=3) { 48 eggGeometry.vertices.push(new THREE.Vector3( 49 eggVerticesArray[i + 0], 50 eggVerticesArray[i + 1], 51 eggVerticesArray[i + 2], 52 )); 53 } 54 console.log(eggGeometry.vertices); 55 } 56 object.scale.set(0.3, 0.3, 0.3); 57 object.rotation.set(180,0,0); 58 // scene.add(object);必要なのは座標なのでシーンには追加しない 59 }); 60 61 62 const geometry = new THREE.Geometry(); 63 // 配置する範囲 64 const SIZE = 5000; 65 // 配置する個数 66 const LENGTH = 80000; 67 for (let i = 0; i < LENGTH; i++) { 68 geometry.vertices.push(new THREE.Vector3( 69 SIZE * (Math.random() - 0.5), 70 SIZE * (Math.random() - 0.5), 71 SIZE * (Math.random() - 0.5), 72 )); 73 } 74 // パーティクルを作成 75 const material = new THREE.PointsMaterial({ 76 size: 5, 77 color: 0x0eff7d, 78 map: new THREE.TextureLoader().load('imgs/snow.png'), 79 blending: THREE.AdditiveBlending, 80 transparent: true, 81 depthWrite: false, 82 }); 83 // 物体を作成 84 const mesh = new THREE.Points(geometry, material); 85 scene.add(mesh); 86 87 function xxx() { 88 for (var i = 0; i < eggGeometry.vertices.length; i++) { 89 TweenMax.to(geometry.vertices[i], 1, { 90 x: eggGeometry.vertices[i].x, 91 y: eggGeometry.vertices[i].y, 92 z: eggGeometry.vertices[i].z, 93 }, 0); 94 } 95 } 96 97 setTimeout(function() { 98 xxx(); 99 }, 1000); 100 tick(); 101 // 毎フレーム時に実行されるループイベントです 102 function tick() { 103 rot += 0.05; 104 // ラジアンに変換する 105 const radian = rot * Math.PI / 180; 106 // 角度に応じてカメラの位置を設定 107 camera.position.x = 100 * Math.sin(radian); 108 camera.position.y = 10 * Math.sin(radian); 109 camera.position.z = 100 * Math.cos(radian); 110 // 原点方向を見つめる 111 camera.lookAt(new THREE.Vector3(0, 0, 0)); 112 // mesh.rotation.y += 0.01; 113 // レンダリング 114 renderer.render(scene, camera); 115 requestAnimationFrame(tick); 116 geometry.verticesNeedUpdate = true; 117 geometry.elementNeedUpdate = true; 118 geometry.computeBoundingSphere(); 119 eggGeometry.verticesNeedUpdate = true; 120 eggGeometry.elementNeedUpdate = true; 121 eggGeometry.computeBoundingSphere(); 122 } 123 124 } 125 </script> 126</head> 127 128<body> 129 <canvas id="myCanvas"></canvas> 130</body> 131 132</html> 133
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。