更新
- 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.CameraやTHREE.Scene、タッチイベントなどを保持するORE.BaseSceneを継承したクラスを作成します。
コンストラクタには後でつくる、ORE.ControllerからのTHREE.WebGLRendererを渡します。
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があります。
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();
} );
最小構成は以上です。これだけで、こんな絵が出ます。
まだまだいっぱいあるよ、ユーティリティ
ore-threeには自分的に需要のあるクラスをどしどし詰め込んでいるのでいくつかご紹介します。
サンプルコードはGitにもあげています。
Github: ore-three-ts (examples)
ORE.PostProcessing
ポストプロセシングです。three.js公式のものより手軽さを重視しました。
GitHub: PostProcessingScene
使い方
-
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.fsvarying 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); } -
renderメソッドでレンダリングthis.pp.render(this.scene,this.camera);renderメソッドはレンダリングソースとしてSceneとCameraを渡す以外にも、テクスチャを渡すこともできます。
また、最後の引数ではオフスクリーンレンダリングをするかのフラグを渡すこともできます。
オフスクリーンレンダリングをした場合、レンダリング結果は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要素の背景で好きなシェーダーを描画することができます。
使い方
-
コンストラクタに渡すパラメータは以下のようになっています。
{ dom: /* DOM要素 */, fragmentShader: /* フラグメントシェーダー */, uniforms: /* uniform変数 */ }これをコンストラクタに渡します。
THREE.Object3Dを継承しているのでそのままTHREE.Sceneにaddすることができます。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); -
DOMの形や位置が変わったタイミングで
updateDomメソッドを実行します。this.domglsl.updateDom();
ORE.MouseRotator
MouseRotatorはマウスやタッチ操作で簡単にオブジェクトをくるくる回すことができるクラスです。
こんな感じの動きになります。
Ore-GL: Ring
使い方
-
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); -
マウスの移動量を渡す
BaseSceneが持っているcursorからマウスの移動量deltaXとdeltaYが取得できるのでそれをTHREE.Vector2型にして渡します。onTouchMove(e) { this.rotator.addVelocity(new THREE.Vector2(this.cursor.deltaX,this.cursor.deltaY)); } -
毎フレームおきに
updateをかけるthis.rotator.update()
ORE.TransformAnimator
オブジェクトの移動と回転の簡単な補完をしてくれます。
使い方
-
TransformAnimatorを作成
コントロールしたいオブジェクトをコンストラクタに渡します。this.transformAnimator = new ORE.TransformAnimator(this.box); -
TransformAnimatorを毎フレーム更新します。
引数にdeltaTimeを渡すと、フレームレートが落ちた場合でも移動速度が落ちなくなります。animate(){ this.transformAnimator.update(this.deltaTime); } -
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だけ使う**みたいなこともできるので、よかったらインストールしてみてください。
また、開発はゆるふわに行なっています。
気まぐれでクラス名の変更とかしちゃったりするので、遊びや参考程度に使うようお願いします。
