8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

three.jsをもっと手軽にするユーティリティパッケージ「ore-three」

Last updated at Posted at 2019-05-20

###更新

  • 2019/06/20 v.0.2.1更新

概要

three.jsむちゃくちゃ便利ですよね...
もう僕はこれなしにWebGLを動かすなんて無理です(甘え)
なのですが、three.jsですら何個もプロジェクトを作っていると、シーンとかレンダラーとかリサイズとかマウスとか.... まあまあめんどくさいですよね。

そんなめんどっちい事を全て忘れられるパッケージを作ったので紹介します。
名付けてore-three です。 ネーミングセンスを疑います。

npm : ore-three-ts
GitHub : ore-three-ts

名前からもわかる通り、TypeScriptで作ってます。多分jsでも動かせると思います。

使い方

1. ore-threeをゲットする

$ npm install ore-three-ts

これだけ!

npmを使いたくない人はこいつをどうぞ。
github: ore-three-ts (build)

2.インポート

ore-threeをインポートします。
ビルド版を使う場合は多分OREオブジェクトが使えるようになっていると思います。

import * as ORE from 'ore-three-ts';

4. シーンを作成

THREE.CameraTHREE.Scene、タッチイベントなどを保持するORE.BaseSceneを継承したクラスを作成します。
コンストラクタには後でつくる、ORE.ControllerからのTHREE.WebGLRendererを渡します。

MainScene.js
import * as ORE from 'ore-three-ts';
import * as THREE from 'three';

export default class MainScene extends ORE.BaseScene{
	constructor(renderer){
		super(renderer);
		this.camera.position.set(0, 1.5, 3);
		this.camera.lookAt(0, 0, 0);
		
		let geo = new THREE.BoxGeometry(1,1,1);
		let mat = new THREE.MeshNormalMaterial();
		this.box = new THREE.Mesh(geo,mat);
		this.scene.add(this.box);
	}

	animate(){
		this.renderer.render(this.scene, this.camera);
	}

	onResize(width,height){
		super.onResize(width, height);
	}

	onTouchStart(e) {
	}

	onTouchMove(e) {
	}

	onTouchEnd(e) {
	}

	onWheel(e) {
	}
}

onTouch~~onWheelは画面クリック、タッチ、マウスホイール時に呼ばれるメソッドです。

3.ORE.Controllerを作成、シーンをセット

レンダラーの作成・保持、リサイズ、アニメーションループをしてくれる、ORE.Controllerを作成します。 Controllerのコンストラクタに渡すパラメータはTHREE.WebGLRendererのパラメータを継承したもので、追加項目としてretina解像度に対応させるためのretina: boolがあります。

index.js
import * as ORE from '../../src/';
import OREScene from './scenes/MainScene';

class APP {

	constructor() {
		
		this.controller = new ORE.Controller( {

			canvas: document.querySelector( "#canvas" ),
			retina: false,
			alpha: false,

		} );
	
		this.controller.setScene( OREScene );

	}

}

window.addEventListener( 'load', ()=>{

	let app = new APP();

} );

最小構成は以上です。これだけで、こんな絵が出ます。

スクリーンショット 2019-05-20 23.21.51.png

まだまだいっぱいあるよ、ユーティリティ

ore-threeには自分的に需要のあるクラスをどしどし詰め込んでいるのでいくつかご紹介します。
サンプルコードはGitにもあげています。
Github: ore-three-ts (examples)

ORE.PostProcessing

ポストプロセシングです。three.js公式のものより手軽さを重視しました。
GitHub: PostProcessingScene

使い方

  1. ORE.PostProcessを生成
    複数のポストプロセスを一気にかけられるようになっています。
    一つのポストプロセスは以下のオブジェクトで定義されます。

    {
    	fragmentShader: /* ポストプロセス用のフラグメントシェーダ */,
    	uniforms: /* フラグメントシェーダーに渡すuniform変数 */
    }
    

    これを配列にしてコンストラクタに渡します。

    this.ppParam = [
    	{
    		fragmentShader: ppFrag,
    		uniforms:{
    			time:{
    				value: 0
    			}
    		}
    	}
    ]
    
    this.pp = new ORE.PostProcessing(this.renderer,this.ppParam);
    

    フラグメントシェーダーにはuvがvarying変数vUv、一つ前のレンダリング結果がuniform変数backbufferとして入力されます。

    ppFrag.fs
    varying vec2 vUv;
    uniform sampler2D backbuffer;
    
    uniform float time;
    
    float random (vec2 st) {
    	return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123);
    }
    
    void main(void){
    	vec3 c = texture2D(backbuffer,vUv).xyz;
    	c += random(vUv + time);
    	gl_FragColor = vec4(c,1.0);
    }
    
  2. renderメソッドでレンダリング

    this.pp.render(this.scene,this.camera);
    

    renderメソッドはレンダリングソースとしてSceneCameraを渡す以外にも、テクスチャを渡すこともできます
    また、最後の引数ではオフスクリーンレンダリングをするかのフラグを渡すこともできます。
    オフスクリーンレンダリングをした場合、レンダリング結果はgetResultTextureメソッドで取得できます。

    //シーンとカメラをソースに、オフスクリーンレンダリング
    this.postprocess1.render(this.scene,this.camera,true);
    
    //postprocess1のレンダリング結果をテクスチャとして取得
    let pp1_Result = this.postprocess1.getResultTexture();
    
    //postprocess1のレンダリング結果をソースとしてpostprocess2をディスプレイに出力
    this.postprocess2.render(pp1_Result,false);
    

ORE.DomGLSL

僕的にとても便利なクラスです。
HTMLの要素を渡せばそのサイズに合わせた長方形のメッシュが生成されます。
独自のフラグメントシェーダーを渡し、特定HTML要素の背景で好きなシェーダーを描画することができます。

使い方

  1. コンストラクタに渡すパラメータは以下のようになっています。

    {
    	dom: /* DOM要素 */,
    	fragmentShader: /* フラグメントシェーダー */,
    	uniforms: /* uniform変数 */
    }
    

    これをコンストラクタに渡します。
    THREE.Object3Dを継承しているのでそのままTHREE.Sceneaddすることができます。

    this.param = {
    	dom: document.querySelector('.dom-glsl'),
    	fragmentShader: frag,
    	uniforms: {
    		time:{ value : 0 } 
    	}
    }
    
    this.domglsl = new ORE.DomGLSL(this.param);
    this.scene.add(this.domglsl);
    
  2. DOMの形や位置が変わったタイミングでupdateDomメソッドを実行します。

    this.domglsl.updateDom();
    

こんな感じでDOMに合わせたメッシュが生成されます。
image.png

ORE.MouseRotator

MouseRotatorはマウスやタッチ操作で簡単にオブジェクトをくるくる回すことができるクラスです。
こんな感じの動きになります。
Ore-GL: Ring

使い方

  1. ORE.MouseRotatorを作成

    回転を加えたいオブジェクトを渡します。

    let boxGeo = new THREE.BoxGeometry(1, 1, 1);
    let boXMat = new THREE.MeshNormalMaterial();
    this.box = new THREE.Mesh(boxGeo, boXMat);
    this.scene.add(this.box);
    
    this.rotator = new ORE.MouseRotator(this.box);
    
  2. マウスの移動量を渡す

    BaseSceneが持っているcursorからマウスの移動量deltaXdeltaYが取得できるのでそれをTHREE.Vector2型にして渡します。

    onTouchMove(e) {
    	this.rotator.addVelocity(new THREE.Vector2(this.cursor.deltaX,this.cursor.deltaY));
    }
    
  3. 毎フレームおきにupdateをかける

    this.rotator.update()
    

ORE.TransformAnimator

オブジェクトの移動と回転の簡単な補完をしてくれます。

使い方

  1. TransformAnimatorを作成
    コントロールしたいオブジェクトをコンストラクタに渡します。

    this.transformAnimator = new ORE.TransformAnimator(this.box);
    
  2. TransformAnimatorを毎フレーム更新します。  
    引数にdeltaTimeを渡すと、フレームレートが落ちた場合でも移動速度が落ちなくなります。

    animate(){
    	this.transformAnimator.update(this.deltaTime);
    }
    
  3. moveメソッドを実行し、オブジェクトを移動
    引数は 位置,回転,移動時間,移動完了時のコールバックになっています。

    let nextPos = new THREE.Vector3(10,0,0);
    let nextRot = new THREE.Euler(0,Math.PI * 2,0);
    
    this.transformAnimator.move(nextPos,nextRot,1,callBack);
    

回転がTHREE.Eulerでの指定なので、2軸以上指定するのは結構厳しいです。  
THREE.Quaternionへの変更を検討中です。

最後に

長々とオレオレライブラリを解説しましたが、これらはすべて、three.jsを使った追加機能みたいなものなので、例えば**ORE.Controllerは使わないで、ORE.PostProcessingだけ使う**みたいなこともできるので、よかったらインストールしてみてください。

また、開発はゆるふわに行なっています。
気まぐれでクラス名の変更とかしちゃったりするので、遊びや参考程度に使うようお願いします

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?