From 07dff3d7f901eabf090ff74a5ecbfba0fd9033fc Mon Sep 17 00:00:00 2001 From: "mipha.ly" Date: Mon, 25 Mar 2019 14:43:37 +0800 Subject: [PATCH] add shaderPass & renderPass --- src/core/engine/renderpass.js | 45 ++++++++++++++++++++--------- src/core/engine/shaderPass.js | 26 +++++++++++++++++ src/layer/render/heatmap/heatmap.js | 2 +- 3 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 src/core/engine/shaderPass.js diff --git a/src/core/engine/renderpass.js b/src/core/engine/renderpass.js index f6d3f0c0df..9c1f596614 100644 --- a/src/core/engine/renderpass.js +++ b/src/core/engine/renderpass.js @@ -1,13 +1,14 @@ import * as THREE from '../three'; +import Util from '../../util'; export default class RenderPass { constructor(cfg) { - this.scene; - this.camera = cfg.camera; - this.renderer = cfg.renderer; - this.clearColor = cfg.clear.clearColor; - this.clearAlpha = cfg.clear.clearAlpha; - this.size = cfg.size ? cfg.size : cfg.renderer.getSize(); + const defaultCfg = this._getDefaultCfg(); + Util.assign(this, defaultCfg, cfg); + this._init(); + } + + _getDefaultCfg() { const defaultRenderCfg = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, @@ -15,16 +16,30 @@ export default class RenderPass { stencilBuffer: false, depthBuffer: false }; - this.renderCfg = cfg.renderCfg ? cfg.renderCfg : defaultRenderCfg; - this._init(cfg); + return { + size: null, + renderCfg: defaultRenderCfg, + clearColor: 0x000000, + clearAlpha: 0.0, + renderToScreen: false, + renderTarget: true + }; } _init() { this.scene = new THREE.Scene(); - this.pass = new THREE.WebGLRenderTarget(this.size.width, this.size.height, this.renderCfg); + if (this.renderTarget) { + const size = this.size ? this.size : this.renderer.getSize(); + this.renderTarget = new THREE.WebGLRenderTarget(size.width, size.height, this.renderCfg); + this.texture = this.renderTarget.texture; + } this.originClearColor = this.renderer.getClearColor(); this.originClearAlpha = this.renderer.getClearAlpha(); - this.texture = this.pass.texture; + } + + setSize(width, height) { + this.size = { width, height }; + this.renderTarget && this.renderTarget.setSize(width, height); } add(mesh) { @@ -36,10 +51,14 @@ export default class RenderPass { } render() { - this.renderer.setClearColor(this.clearColor, this.clearAlpha); - this.renderer.render(this.scene, this.camera, this.pass, true); - this.renderer.setRenderTarget(null); + if (this.renderToScreen) { + this.renderer.setRenderTarget(null); + this.renderer.render(this.scene, this.camera); + } else { + this.renderTarget && this.renderer.render(this.scene, this.camera, this.renderTarget, true); + this.renderer.setRenderTarget(null); + } this.renderer.setClearColor(this.originClearColor, this.originClearAlpha); } } diff --git a/src/core/engine/shaderPass.js b/src/core/engine/shaderPass.js new file mode 100644 index 0000000000..31ca2d3baf --- /dev/null +++ b/src/core/engine/shaderPass.js @@ -0,0 +1,26 @@ +import * as THREE from '../three'; +import RenderPass from './renderpass'; + +export default class ShaderPass extends RenderPass { + + constructor(cfg) { + super({ + size: { width: 2, height: 2 }, + ...cfg + }); + } + + _init(cfg) { + super(cfg); + this.camera = new THREE.OrthographicCamera(-this.size.width / 2, this.size.width / 2, this.size.height / 2, -this.size.height / 2, 0, 100); + this.material = new THREE.ShaderMaterial({ + vertexShader: this.vertexShader, + fragmentShader: this.fragmentShader, + uniforms: this.uniforms, + ...this.matCfg + }); + this.quad = new THREE.Mesh(new THREE.PlaneBufferGeometry(this.size.width, this.size.height), this.material); + this.quad.frustumCulled = false; // Avoid getting clipped + this.scene.add(this.quad); + } +} diff --git a/src/layer/render/heatmap/heatmap.js b/src/layer/render/heatmap/heatmap.js index 87a5322b7e..edbfca5251 100644 --- a/src/layer/render/heatmap/heatmap.js +++ b/src/layer/render/heatmap/heatmap.js @@ -78,7 +78,7 @@ export function updateIntensityPass(layer) { mesh.material.uniforms.u_zoom.value = zoom; const passWidth = Math.min(8000, Math.pow(zoom, 2.0) * 250); const passHeight = passWidth * (bbox.height / bbox.width); - layer.intensityPass.pass.setSize(passWidth, passHeight); + layer.intensityPass.setSize(passWidth, passHeight); layer.intensityPass.render(); }