UNPKG

ogl-typescript

Version:

TypeScript port of OGL WebGL Library

101 lines (97 loc) 3.7 kB
// TODO: Destroy render targets if size changed and exists import { Program } from '../core/Program'; import { Mesh } from '../core/Mesh'; import { RenderTarget } from '../core/RenderTarget'; import { Triangle } from './Triangle'; export class Post { constructor(gl, { width, height, dpr, wrapS = gl.CLAMP_TO_EDGE, wrapT = gl.CLAMP_TO_EDGE, minFilter = gl.LINEAR, magFilter = gl.LINEAR, geometry = new Triangle(gl), targetOnly = null, } = {}) { this.gl = gl; this.options = { wrapS, wrapT, minFilter, magFilter }; this.passes = []; this.geometry = geometry; this.uniform = { value: null }; this.targetOnly = targetOnly; const fbo = (this.fbo = { read: null, write: null, swap: () => { let temp = fbo.read; fbo.read = fbo.write; fbo.write = temp; }, }); this.resize({ width, height, dpr }); } addPass({ vertex = defaultVertex, fragment = defaultFragment, uniforms = {}, textureUniform = 'tMap', enabled = true } = {}) { uniforms[textureUniform] = { value: this.fbo.read.texture }; const program = new Program(this.gl, { vertex, fragment, uniforms }); const mesh = new Mesh(this.gl, { geometry: this.geometry, program }); const pass = { mesh, program, uniforms, enabled, textureUniform, }; this.passes.push(pass); return pass; } resize({ width, height, dpr } = {}) { if (dpr) this.dpr = dpr; if (width) { this.width = width; this.height = height || width; } dpr = this.dpr || this.gl.renderer.dpr; width = Math.floor((this.width || this.gl.renderer.width) * dpr); height = Math.floor((this.height || this.gl.renderer.height) * dpr); this.options.width = width; this.options.height = height; this.fbo.read = new RenderTarget(this.gl, this.options); this.fbo.write = new RenderTarget(this.gl, this.options); } // Uses same arguments as renderer.render, with addition of optional texture passed in to avoid scene render render({ scene = null, camera = null, texture = null, target = null, update = true, sort = true, frustumCull = true }) { const enabledPasses = this.passes.filter((pass) => pass.enabled); if (!texture) { this.gl.renderer.render({ scene, camera, target: enabledPasses.length || (!target && this.targetOnly) ? this.fbo.write : target, update, sort, frustumCull, }); this.fbo.swap(); } enabledPasses.forEach((pass, i) => { pass.mesh.program.uniforms[pass.textureUniform].value = !i && texture ? texture : this.fbo.read.texture; this.gl.renderer.render({ scene: pass.mesh, target: i === enabledPasses.length - 1 && (target || !this.targetOnly) ? target : this.fbo.write, clear: true, }); this.fbo.swap(); }); this.uniform.value = this.fbo.read.texture; } } const defaultVertex = /* glsl */ ` attribute vec2 uv; attribute vec2 position; varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 0, 1); } `; const defaultFragment = /* glsl */ ` precision highp float; uniform sampler2D tMap; varying vec2 vUv; void main() { gl_FragColor = texture2D(tMap, vUv); } `; //# sourceMappingURL=Post.js.map