###更新
- 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
だけ使う**みたいなこともできるので、よかったらインストールしてみてください。
また、開発はゆるふわに行なっています。
気まぐれでクラス名の変更とかしちゃったりするので、遊びや参考程度に使うようお願いします。