@vci/quick-three
Version:
quick three
155 lines (147 loc) • 4.88 kB
JavaScript
import { QtPlugin } from "./QtPlugin";
import { addCss, mergeDeep } from "@vci/helper";
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 };