UNPKG

@vci/quick-three

Version:

quick three

156 lines (148 loc) 5.09 kB
import { QtPlugin } from "./QtPlugin"; import { addCss } from "@vci/helper/src/element"; import { mergeDeep } from "@vci/helper/src/object"; import { ACESFilmicToneMapping, AgXToneMapping, BasicShadowMap, CineonToneMapping, CustomToneMapping, LinearSRGBColorSpace, LinearToneMapping, NeutralToneMapping, NoToneMapping, PCFShadowMap, PCFSoftShadowMap, ReinhardToneMapping, SRGBColorSpace, VSMShadowMap, WebGLRenderer } from "three"; import { createTweenModifier } from "./../helper/TweenHelper"; class PluginRenderer extends QtPlugin { static namespace = "rendererGl"; constructor(qt, option) { super(qt, mergeDeep({ params: { powerPreference: "high-performance", antialias: false, stencil: false, depth: false, alpha: true, // 超大模型,巨大的比例差异处理 logarithmicDepthBuffer: true }, toneMapping: NoToneMapping, toneMappingExposure: 1, enableShadow: true, shadowMapType: PCFSoftShadowMap, releaseWebGLContextOnDestroy: true }, option)); } init() { super.init(); const { qt } = this; const { params, enableShadow, shadowMapType, toneMapping, toneMappingExposure } = this.option; this.renderer = qt.renderer = this.createRenderer(qt, params); this.createRendererHelper(qt, this.renderer); if (!params.context) { qt.el.appendChild(this.renderer.domElement); addCss(this.renderer.domElement, { position: "relative", zIndex: 1 }); } qt.renderer.debug.checkShaderErrors = qt.debug; qt.renderer.info.autoReset = false; qt.renderer.toneMapping = toneMapping; qt.renderer.toneMappingExposure = toneMappingExposure; qt.renderer.shadowMap.type = shadowMapType; qt.renderer.shadowMap.enabled = enableShadow; this.addEventListener(QtPlugin.Events.Render, () => { if (!qt.effect) { this.renderer.render(this.qt.scene, this.qt.camera); this.renderer.info.reset(); } }); this.addEventListener(QtPlugin.Events.Resize, e => this.renderer.setSize(e.detail.width, e.detail.height)); } createRenderer(qt, params) { const renderer = new WebGLRenderer(params); renderer.setPixelRatio(qt.dpr); renderer.setSize(qt.elWidth, qt.elHeight, true); renderer.domElement.removeAttribute("data-engine"); if (qt.debug && qt.gui) { const gui = qt.gui.guis.renderer; gui .add(renderer, "toneMapping", { "NoToneMapping": NoToneMapping, "LinearToneMapping": LinearToneMapping, "ReinhardToneMapping": ReinhardToneMapping, "CineonToneMapping": CineonToneMapping, "ACESFilmicToneMapping": ACESFilmicToneMapping, "AgXToneMapping": AgXToneMapping, "NeutralToneMapping": NeutralToneMapping, "CustomToneMapping": CustomToneMapping }) .name("色调") .listen(); gui .add(renderer, "toneMappingExposure", 0, 2) .name("色调曝光度") .listen(); gui .add(renderer, "outputColorSpace", { "SRGBColorSpace": SRGBColorSpace, "LinearSRGBColorSpace": LinearSRGBColorSpace }) .name("颜色空间") .onChange(e => { renderer.outputColorSpace = e; qt.helper.updateSceneMaterials(); }) .listen(); const guiShadow = gui.addFolder("阴影"); guiShadow .add(renderer.shadowMap, "enabled") .name("是否启用阴影贴图") .onChange(() => { renderer.shadowMap.type = PCFSoftShadowMap; qt.helper.updateSceneMaterials(); }) .listen(); guiShadow .add(renderer.shadowMap, "type", { "BasicShadowMap": BasicShadowMap, "PCFShadowMap": PCFShadowMap, "PCFSoftShadowMap": PCFSoftShadowMap, "VSMShadowMap": VSMShadowMap }) .onChange(() => qt.helper.updateSceneMaterials()).name("阴影类型") .listen(); } return renderer; } createRendererHelper(qt, renderer) { renderer.modifyToneMappingExposure = createTweenModifier( qt.tw, { instance: renderer, keyModifyProperty: "toneMappingExposure", twKey: `renderer.modifyToneMappingExposure` } ); renderer.resetToneMappingExposure = async twOption => await renderer.modifyToneMappingExposure(renderer._toneMappingExposure, twOption); } destroy() { super.destroy(); const renderer = this.renderer; renderer.dispose(); // #正确释放WebGL上下文 if (this.option.releaseWebGLContextOnDestroy) { renderer.getContext().getExtension("WEBGL_lose_context").loseContext(); renderer.domElement.parentNode && renderer.domElement.parentNode.removeChild(renderer.domElement); } console.info(renderer.info); } } export { PluginRenderer };