TABLE OF CONTENTS
概要
WebGLRenderTargetでオフスクリーンレンダリングするフローをメモしました。
※ Three.js r156
フレームバッファオブジェクトの生成
// fbo作成
const size = 1024; // テクスチャの解像度
const fbo = new THREE.WebGLRenderTarget(size, size);
フレームバッファオブジェクト用のシーンを作成
const fboScene = new THREE.Scene();
テクスチャを板ポリに貼り付ける
画面サイズぴったりにする場合は板ポリのサイズを2
にします。
サイズが2の理由は gl_Position
の座標系が下記の画像のように「-1.0 ~ 1.0」の正規化デバイス座標空間になるためです。
const geometry = new THREE.PlaneGeometry(2, 2, 1, 1);
const material = new THREE.ShaderMaterial({
fragmentShader: fragmentShader,
vertexShader: vertexShader,
uniforms: {
uTexture: { type: "t", value: this.fbo.texture },
},
});
const fboMesh = new THREE.Mesh(geometry, material);
fboScene.add(fboMesh);
// fragment shader
uniform sampler2D uTexture;
varying vec2 vUv;
void main( void ) {
vec4 t = texture2D(uTexture, vUv);
gl_FragColor = LinearTosRGB(t);
}
LinearTosRGB で出力しているのは WebGLRenderTargetで色味が変わってしまう で確認してください🙏
// vertex shader
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position, 1.0);
}
レンダリング
- フレームバッファをバインドする(有効化)
- レンダリング結果をフレームバッファのテクスチャに焼き付ける
- フレームバッファのバインドを解除する
- 板ポリのシーンをレンダリングする
// requestAnimationFrame
renderer.setRenderTarget(fbo);
renderer.render(scene, camera);
renderer.setRenderTarget(null);
renderer.render(fboScene, camera);
その他
解像度をデバイスによって調整する
▼ 解像度を固定している場合 ▼
▼ 解像度をデバイスによって変更している場合 ▼
const clamp = (num, min, max) => {
return min > num ? min : max < num ? max : num;
};
const pixelRatio = clamp(window.devicePixelRatio, 1, 2);
const size = 1024;
const fbo = new THREE.WebGLRenderTarget(size * pixelRatio, size * pixelRatio);
WebGLRenderTargetのオプションについて
const type = /(iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : THREE.FloatType;
const pixelRatio = clamp(window.devicePixelRatio, 1, 2);
const size = 1024;
const fbo = new THREE.WebGLRenderTarget(size * pixelRatio, size * pixelRatio, {
// 深度バッファ
depthBuffer: false,
// ステンシルバッファ
stencilBuffer: false,
// フォーマット
format: THREE.RGBAFormat,
// テクスチャのタイプ
type: THREE.UnsignedByteType,
// 出力時のエンコード設定
colorSpace: THREE.SRGBColorSpace,
// THREE.NoColorSpace:
// THREE.SRGBColorSpace:
// THREE.LinearSRGBColorSpace:
// テクスチャが拡大縮小するときの設定
magFilter: THREE.LinearFilter,
minFilter: THREE.LinearFilter,
// THREE.LinearFilter: 対象のピクセルに近い4つのピクセルから平均した色になる
// THREE.NearestFilter: 対象のピクセルに最も近い色になる
// テクスチャのラッピングの設定
wrapS: THREE.ClampToEdgeWrapping, // st.s === uv.x
wrapT: THREE.ClampToEdgeWrapping, // st.t === uv.y
// THREE.RepeatWrapping: 無限に繰り返す
// THREE.ClampToEdgeWrapping: テクスチャの端のピクセルがメッシュの端まで引き伸ばされる
// THREE.MirroredRepeatWrapping: 無限に繰り返しながら繰り返しでミラーリングする
});