UNPKG

bytev-charts

Version:

基于echarts和JavaScript及ES6封装的一个可以直接调用的图表组件库,内置主题设计,简单快捷,且支持用户自定义配置; npm 安装方式: npm install bytev-charts 若启动提示还需额外install插件,则运行 npm install @babel/runtime-corejs2 即可;

251 lines (229 loc) 10.3 kB
import _Object$assign from "@babel/runtime-corejs2/core-js/object/assign"; import _Object$create from "@babel/runtime-corejs2/core-js/object/create"; import "core-js/modules/es.number.to-fixed.js"; import "core-js/modules/es.array.join.js"; import "core-js/modules/es.function.name.js"; import { LinearFilter, LinearMipmapLinearFilter, MeshBasicMaterial, NoBlending, RGBAFormat, ShaderMaterial, UniformsUtils, WebGLRenderTarget } from "../../../build/three.module.js"; import { Pass } from "../postprocessing/Pass.js"; import { CopyShader } from "../shaders/CopyShader.js"; import { LuminosityShader } from "../shaders/LuminosityShader.js"; import { ToneMapShader } from "../shaders/ToneMapShader.js"; /** * Generate a texture that represents the luminosity of the current scene, adapted over time * to simulate the optic nerve responding to the amount of light it is receiving. * Based on a GDC2007 presentation by Wolfgang Engel titled "Post-Processing Pipeline" * * Full-screen tone-mapping shader based on http://www.graphics.cornell.edu/~jaf/publications/sig02_paper.pdf */ var AdaptiveToneMappingPass = function AdaptiveToneMappingPass(adaptive, resolution) { Pass.call(this); this.resolution = resolution !== undefined ? resolution : 256; this.needsInit = true; this.adaptive = adaptive !== undefined ? !!adaptive : true; this.luminanceRT = null; this.previousLuminanceRT = null; this.currentLuminanceRT = null; if (CopyShader === undefined) console.error("AdaptiveToneMappingPass relies on CopyShader"); var copyShader = CopyShader; this.copyUniforms = UniformsUtils.clone(copyShader.uniforms); this.materialCopy = new ShaderMaterial({ uniforms: this.copyUniforms, vertexShader: copyShader.vertexShader, fragmentShader: copyShader.fragmentShader, blending: NoBlending, depthTest: false }); if (LuminosityShader === undefined) console.error("AdaptiveToneMappingPass relies on LuminosityShader"); this.materialLuminance = new ShaderMaterial({ uniforms: UniformsUtils.clone(LuminosityShader.uniforms), vertexShader: LuminosityShader.vertexShader, fragmentShader: LuminosityShader.fragmentShader, blending: NoBlending }); this.adaptLuminanceShader = { defines: { "MIP_LEVEL_1X1": (Math.log(this.resolution) / Math.log(2.0)).toFixed(1) }, uniforms: { "lastLum": { value: null }, "currentLum": { value: null }, "minLuminance": { value: 0.01 }, "delta": { value: 0.016 }, "tau": { value: 1.0 } }, vertexShader: ["varying vec2 vUv;", "void main() {", " vUv = uv;", " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join('\n'), fragmentShader: ["varying vec2 vUv;", "uniform sampler2D lastLum;", "uniform sampler2D currentLum;", "uniform float minLuminance;", "uniform float delta;", "uniform float tau;", "void main() {", " vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );", " vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );", " float fLastLum = max( minLuminance, lastLum.r );", " float fCurrentLum = max( minLuminance, currentLum.r );", //The adaption seems to work better in extreme lighting differences //if the input luminance is squared. " fCurrentLum *= fCurrentLum;", // Adapt the luminance using Pattanaik's technique " float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));", // "fAdaptedLum = sqrt(fAdaptedLum);", " gl_FragColor.r = fAdaptedLum;", "}"].join('\n') }; this.materialAdaptiveLum = new ShaderMaterial({ uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms), vertexShader: this.adaptLuminanceShader.vertexShader, fragmentShader: this.adaptLuminanceShader.fragmentShader, defines: _Object$assign({}, this.adaptLuminanceShader.defines), blending: NoBlending }); if (ToneMapShader === undefined) console.error("AdaptiveToneMappingPass relies on ToneMapShader"); this.materialToneMap = new ShaderMaterial({ uniforms: UniformsUtils.clone(ToneMapShader.uniforms), vertexShader: ToneMapShader.vertexShader, fragmentShader: ToneMapShader.fragmentShader, blending: NoBlending }); this.fsQuad = new Pass.FullScreenQuad(null); }; AdaptiveToneMappingPass.prototype = _Object$assign(_Object$create(Pass.prototype), { constructor: AdaptiveToneMappingPass, render: function render(renderer, writeBuffer, readBuffer, deltaTime /*, maskActive*/ ) { if (this.needsInit) { this.reset(renderer); this.luminanceRT.texture.type = readBuffer.texture.type; this.previousLuminanceRT.texture.type = readBuffer.texture.type; this.currentLuminanceRT.texture.type = readBuffer.texture.type; this.needsInit = false; } if (this.adaptive) { //Render the luminance of the current scene into a render target with mipmapping enabled this.fsQuad.material = this.materialLuminance; this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture; renderer.setRenderTarget(this.currentLuminanceRT); this.fsQuad.render(renderer); //Use the new luminance values, the previous luminance and the frame delta to //adapt the luminance over time. this.fsQuad.material = this.materialAdaptiveLum; this.materialAdaptiveLum.uniforms.delta.value = deltaTime; this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture; this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture; renderer.setRenderTarget(this.luminanceRT); this.fsQuad.render(renderer); //Copy the new adapted luminance value so that it can be used by the next frame. this.fsQuad.material = this.materialCopy; this.copyUniforms.tDiffuse.value = this.luminanceRT.texture; renderer.setRenderTarget(this.previousLuminanceRT); this.fsQuad.render(renderer); } this.fsQuad.material = this.materialToneMap; this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture; if (this.renderToScreen) { renderer.setRenderTarget(null); this.fsQuad.render(renderer); } else { renderer.setRenderTarget(writeBuffer); if (this.clear) renderer.clear(); this.fsQuad.render(renderer); } }, reset: function reset() { // render targets if (this.luminanceRT) { this.luminanceRT.dispose(); } if (this.currentLuminanceRT) { this.currentLuminanceRT.dispose(); } if (this.previousLuminanceRT) { this.previousLuminanceRT.dispose(); } var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; // was RGB format. changed to RGBA format. see discussion in #8415 / #8450 this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars); this.luminanceRT.texture.name = "AdaptiveToneMappingPass.l"; this.luminanceRT.texture.generateMipmaps = false; this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars); this.previousLuminanceRT.texture.name = "AdaptiveToneMappingPass.pl"; this.previousLuminanceRT.texture.generateMipmaps = false; // We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader pars.minFilter = LinearMipmapLinearFilter; pars.generateMipmaps = true; this.currentLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars); this.currentLuminanceRT.texture.name = "AdaptiveToneMappingPass.cl"; if (this.adaptive) { this.materialToneMap.defines["ADAPTED_LUMINANCE"] = ""; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture; } //Put something in the adaptive luminance texture so that the scene can render initially this.fsQuad.material = new MeshBasicMaterial({ color: 0x777777 }); this.materialLuminance.needsUpdate = true; this.materialAdaptiveLum.needsUpdate = true; this.materialToneMap.needsUpdate = true; // renderer.render( this.scene, this.camera, this.luminanceRT ); // renderer.render( this.scene, this.camera, this.previousLuminanceRT ); // renderer.render( this.scene, this.camera, this.currentLuminanceRT ); }, setAdaptive: function setAdaptive(adaptive) { if (adaptive) { this.adaptive = true; this.materialToneMap.defines["ADAPTED_LUMINANCE"] = ""; this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture; } else { this.adaptive = false; delete this.materialToneMap.defines["ADAPTED_LUMINANCE"]; this.materialToneMap.uniforms.luminanceMap.value = null; } this.materialToneMap.needsUpdate = true; }, setAdaptionRate: function setAdaptionRate(rate) { if (rate) { this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate); } }, setMinLuminance: function setMinLuminance(minLum) { if (minLum) { this.materialToneMap.uniforms.minLuminance.value = minLum; this.materialAdaptiveLum.uniforms.minLuminance.value = minLum; } }, setMaxLuminance: function setMaxLuminance(maxLum) { if (maxLum) { this.materialToneMap.uniforms.maxLuminance.value = maxLum; } }, setAverageLuminance: function setAverageLuminance(avgLum) { if (avgLum) { this.materialToneMap.uniforms.averageLuminance.value = avgLum; } }, setMiddleGrey: function setMiddleGrey(middleGrey) { if (middleGrey) { this.materialToneMap.uniforms.middleGrey.value = middleGrey; } }, dispose: function dispose() { if (this.luminanceRT) { this.luminanceRT.dispose(); } if (this.previousLuminanceRT) { this.previousLuminanceRT.dispose(); } if (this.currentLuminanceRT) { this.currentLuminanceRT.dispose(); } if (this.materialLuminance) { this.materialLuminance.dispose(); } if (this.materialAdaptiveLum) { this.materialAdaptiveLum.dispose(); } if (this.materialCopy) { this.materialCopy.dispose(); } if (this.materialToneMap) { this.materialToneMap.dispose(); } } }); export { AdaptiveToneMappingPass };