質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.42%
Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

WebGL

WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。

Q&A

解決済

2回答

1850閲覧

Three.jsでの均等配列パーティクル

makino_

総合スコア11

Three.js

Three.jsはWebGLをサポートしているJavaScriptの3D描画用ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

WebGL

WebGL(ウェブジーエル)は、ウェブブラウザで 3次元コンピュータグラフィックスを表示させるための標準仕様です。

0グッド

0クリップ

投稿2021/11/12 09:26

Three.jsのパーティクルで画像のように均等に並んでいるパーティクルを作るのはどうしたらよろしいでしょうか?

また左上から順にフェードインさせる方法がありましたら何かアドバイス頂けると助かります。

イメージ説明

■現在のコード

javascript

1const canvas = document.getElementById('canvas'); 2const scene = new THREE.Scene(); 3 4const renderer = new THREE.WebGLRenderer(); 5renderer.setClearColor(new THREE.Color(0xffffff, 1)); 6renderer.setSize(400, 400); 7canvas.appendChild(renderer.domElement) 8 9const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); 10camera.position.x = 0; 11camera.position.y = 0; 12camera.position.z = 150; 13 14createSprites(); 15ref(); 16 17function createSprites() { 18 let material = new THREE.SpriteMaterial(); 19 20 for(let x = -5; x < 5; x++) { 21 for(let y = -5; y < 5; y++) { 22 let sprite = new THREE.Sprite(material); 23 sprite.position.set(x * 10, y * 10, 0); 24 scene.add(sprite); 25 } 26 } 27} 28 29function ref() { 30 requestAnimationFrame(ref); 31 renderer.render(scene, camera); 32}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

「左上から順にフェードインさせる方法」についての回答です。
① 個々のスプライトのマテリアルに対し、opacity プロパティの値を変化させる方法
② カスタムシェーダを用いて GLSL で制御する方法

②については難易度が格段に上がるので、①での方法を示します。

下記は、GSAP(アニメーションライブラリ)を用いた実装例です。
説明すると長くなりますので、コードを読解したり、いじったりしてみてください。
注意点としては、各マテリアルの制御のためにマテリアルを配列に格納しておく事と、マテリアルをループの中で毎回生成する事です。

※下記は npm で gsap をインストールしてあることを前提としています。npm がもしわからない場合は、CDN で gsap を使う方法もありますので、調べてみてください。

JavaScript

1import { gsap } from 'gsap' 2import * as THREE from 'three' 3 4const canvas = document.getElementById('canvas') 5const scene = new THREE.Scene() 6 7const renderer = new THREE.WebGLRenderer() 8renderer.setClearColor(new THREE.Color('black')) 9renderer.setSize(800, 800) 10canvas.appendChild(renderer.domElement) 11 12const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 1000) 13camera.position.x = 0 14camera.position.y = 0 15camera.position.z = 150 16 17// 個々のスプライトのマテリアルを gsap で制御する為、マテリアルを格納するための配列を準備しておく。 18const spriteMaterials = [] 19 20createSprites() 21ref() 22 23// gsap の stagger という機能を利用することで、連鎖するようなアニメーションが可能 24gsap.to(spriteMaterials, { 25 'opacity': 1, 26 duration: 2, 27 stagger: { 28 grid: [11, 11], 29 each: 0.1, 30 from: "start" 31 } 32}) 33 34function createSprites() { 35 36 for (let x = 0; x <= 10; x++) { 37 38 for (let y = 0; y <= 10; y++) { 39 40 // 個々のマテリアルに対して、別々に(タイミングをずらして)opacity を変化させる為、 41 // ループの中で THREE.SpriteMaterial を毎回生成する必要がある。 42 const material = new THREE.SpriteMaterial({ transparent: true }) 43 material.opacity = 0 44 45 const sprite = new THREE.Sprite(material) 46 47 sprite.position.x = -50 + ( 10 * x ) 48 sprite.position.y = 50 - ( 10 * y ) 49 sprite.position.z = 0 50 51 scene.add(sprite) 52 53 spriteMaterials.push(sprite.material) 54 } 55 } 56} 57 58function ref() { 59 requestAnimationFrame(ref) 60 renderer.render(scene, camera) 61} 62

投稿2021/11/13 00:41

hirotry

総合スコア53

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

質問者さんの貼った画像のような、均等に並んだパーティクルを作るには下記2つの方法を思いつきました。

  • 質問者さんのように THREE.Sprite クラスを用いる
  • THREE.PlaneGeometry, THREE.PointsMaterial, THREE.Points を用いる

以下、THREE.Sprite クラスを用いる方法で説明します。

質問者さんの貼っていただいたコードを拝見すると、惜しいところまで来ているのですが、2点、修正が必要です。
① クリアカラーの設定
② PerspectiveCameraのアスペクト比 もしくは renderer.setSize()の引数

①について
クリアカラーの設定の中で、THREE.Color オブジェクトを作る際の引数の指定が誤っています。
また、THREE.SpriteMaterial の既定の色が白である為、白以外の色(黒など)でクリアカラーを設定しないと、スプライトと背景が同化してしまいます。
下記のように修正してみてください。

JavaScript

1// before 2renderer.setClearColor(new THREE.Color(0xffffff, 1)); 3// after 4renderer.setClearColor(new THREE.Color(0x000000));

②について
renderer.setSize で設定したサイズのアスペクト比(縦横比)と、PerspectiveCamera オブジェクト生成時の引数に渡すアスペクト比が異なっている為、canvas 上には意図しない比率での描画結果になります(縦長もしくは横長に 3D 空間が描画される)。
下記のように修正してみてください。

JavaScript

1// 下記のどちらかを実施 2 3/*---- PerspectiveCamera 生成時に渡す引数を修正する方法 ----*/ 4// before 5const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); 6// after (アス比を1にしちゃう) 7const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 1000); 8 9/*---- renderer.setSize() を修正する方法 ----------------*/ 10// before 11renderer.setSize(400, 400) 12// after (windowのサイズに合わせる) 13renderer.setSize(window.innerWidth, window.innerHeight)

<補足>
setSize をウィンドウ幅に合わせると、ブラウザのデフォルトの余白が邪魔になると思うので、css で下記を入れると解消されます。

css

1html, 2body { 3 overflow: hidden; 4 margin: 0; 5}

質問者さんのコードに上記の修正を行えば、均等なパーティクルが表示されるはずです。


<参考>
下記のドキュメントの Constructor 欄に、スプライトマテリアルの既定色が白である旨が書かれています。
SpriteMaterial


<ついでに>
冒頭でお話しした、THREE.PlaneGeometry, THREE.PointsMaterial, THREE.Points を用いる方法については、下記を使えばできます。

JavaScript

1// Scene オブジェクトを生成する記述以降に下記コードを書く 2scene.add( 3 new THREE.Points( 4 new THREE.PlaneGeometry(100, 100, 10, 10), 5 new THREE.PointsMaterial({ color: 'lightgreen' }) 6 ) 7)

回答が長くなりますので、「左上から順にフェードインさせる方法」については、別で回答します。

投稿2021/11/13 00:08

編集2021/11/13 00:15
hirotry

総合スコア53

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

makino_

2021/11/14 11:48

ご丁寧に回答いただき誠にありがとうございます、、 わかりやすい説明で無事解決、理解することができました! またいくつか方法があることもわかりましたのでそれらの方法も試してみようと思います! 動きの件もとても助かりました、、!
hirotry

2021/11/14 11:52

解決できてよかったです。 WebGL は難しいですが(私も勉強中)、がんばってください!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.42%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問