UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

248 lines (247 loc) 8.3 kB
"use strict"; import { TypedRopNode } from "./_Base"; import { RopType } from "../../poly/registers/nodes/types/Rop"; import { MeshBasicMaterial, CustomBlending } from "three"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { Poly } from "../../Poly"; import { FullScreenQuad } from "../../../modules/three/examples/jsm/postprocessing/Pass"; import { PathTracingRenderer, PhysicalPathTracingMaterial, DenoiseMaterial } from "../../../core/render/PBR/three-gpu-pathtracer"; import { PathTracingRendererContainer } from "./utils/pathTracing/PathTracingRendererContainer"; import { ModuleName } from "../../poly/registers/modules/Common"; const updateWithoutCook = { cook: false, callback: (node) => { PathTracingRendererRopNode.PARAM_CALLBACK_update(node); } }; class PathTracingRendererRopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.realtime = ParamConfig.FOLDER(); /** @param display samples count */ this.displayDebug = ParamConfig.BOOLEAN(1); /** @param useWorker */ this.useWorker = ParamConfig.BOOLEAN(0); /** @param samples */ this.maxSamplesCount = ParamConfig.INTEGER(2 ** 12, { range: [1, 2 ** 12], rangeLocked: [true, false], step: 1 }); /** @param resolutionScale */ this.resolutionScale = ParamConfig.FLOAT(0.5, { range: [0.1, 1], rangeLocked: [true, true], step: 0.01, separatorAfter: true }); /** @param bounces */ this.bounces = ParamConfig.INTEGER(3, { range: [1, 10], rangeLocked: [true, false], ...updateWithoutCook }); /** @param bounces inside transmissive material */ this.transmissiveBounces = ParamConfig.INTEGER(3, { range: [1, 10], rangeLocked: [true, false], ...updateWithoutCook }); /** @param stableNoise*/ this.stableNoise = ParamConfig.BOOLEAN(1, { ...updateWithoutCook }); /** @param multipleImportanceSampling */ this.multipleImportanceSampling = ParamConfig.BOOLEAN(1, { ...updateWithoutCook }); /** @param filterGlossyFactor */ this.filterGlossyFactor = ParamConfig.FLOAT(0.5, { range: [0, 1], rangeLocked: [true, true], ...updateWithoutCook }); /** @param backgroundBlur*/ this.backgroundBlur = ParamConfig.FLOAT(0, { // ...updateWithoutCook, }); /** @param environmentIntensity*/ this.environmentIntensity = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [true, false], ...updateWithoutCook }); this.denoise = ParamConfig.BOOLEAN(1, { separatorBefore: true, ...updateWithoutCook }); this.denoiseSigma = ParamConfig.FLOAT(2.5, { range: [0.01, 12], rangeLocked: [true, true], ...updateWithoutCook }); this.denoiseThreshold = ParamConfig.FLOAT(0.1, { range: [0.01, 1], rangeLocked: [true, true], ...updateWithoutCook }); this.denoiseKSigma = ParamConfig.FLOAT(1, { range: [0, 12], rangeLocked: [true, true], ...updateWithoutCook }); /** @param toggle on to have alpha on (change requires page reload) */ // alpha = ParamConfig.BOOLEAN(1); /** @param toggle on to have antialias on (change requires page reload) */ // antialias = ParamConfig.BOOLEAN(1); /** @param tiles */ this.tiles = ParamConfig.VECTOR2([2, 2], { separatorBefore: true, ...updateWithoutCook }); /** @param force update */ // generate = ParamConfig.BUTTON(null, { // callback: (node: BaseNodeType) => { // PathTracingRendererRopNode.PARAM_CALLBACK_generate(node as PathTracingRendererRopNode); // }, // }); // /** @param reset */ // reset = ParamConfig.BUTTON(null, { // callback: (node: BaseNodeType) => { // PathTracingRendererRopNode.PARAM_CALLBACK_reset(node as PathTracingRendererRopNode); // }, // }); this.sequenceRender = ParamConfig.FOLDER(); /** @param frame range */ this.f = ParamConfig.VECTOR2([0, 100], { label: "Frame Range", ...updateWithoutCook }); /** @param samples */ this.samplesPerAnimationFrame = ParamConfig.INTEGER(20, { range: [1, 1e3], rangeLocked: [true, false], ...updateWithoutCook }); /** @param resolution */ this.resolution = ParamConfig.VECTOR2([512, 512], { ...updateWithoutCook }); /** @param fileName */ this.fileName = ParamConfig.STRING("`$OS`", { ...updateWithoutCook }); this.framePadding = ParamConfig.INTEGER(4, { range: [2, 6], rangeLocked: [true, false], ...updateWithoutCook }); } } const ParamsConfig = new PathTracingRendererRopParamsConfig(); export class PathTracingRendererRopNode extends TypedRopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return RopType.PATH_TRACING; } requiredModules() { return [ModuleName.PBR]; } initializeNode() { super.initializeNode(); Poly.onSceneUpdatedHooks.registerHook(this, this._paramCallbackGenerate.bind(this)); } dispose() { super.dispose(); Poly.onSceneUpdatedHooks.unregisterHook(this); } _createWebGLRenderer(canvas, gl) { const webGLRenderer = Poly.renderersController.defaultWebGLRendererForCanvas(canvas); if (Poly.renderersController.printDebug()) { Poly.renderersController.printDebugMessage(`create renderer from node '${this.path()}'`); } return webGLRenderer; } _createPathTracingRenderer(canvas, gl) { this._webGLRenderer = this._webGLRenderer || this._createWebGLRenderer(canvas, gl); const pathTracingRenderer = new PathTracingRenderer(this._webGLRenderer); pathTracingRenderer.material = new PhysicalPathTracingMaterial(); const fsQuadMat = new MeshBasicMaterial({ map: pathTracingRenderer.target.texture, blending: CustomBlending }); const denoiseMat = new DenoiseMaterial({ map: pathTracingRenderer.target.texture, blending: CustomBlending, premultipliedAlpha: this._webGLRenderer.getContextAttributes().premultipliedAlpha }); const denoiseQuad = new FullScreenQuad(denoiseMat); const fsQuad = new FullScreenQuad(fsQuadMat); const pathTracingRendererContainer = new PathTracingRendererContainer({ node: this, webGLRenderer: this._webGLRenderer, pathTracingRenderer, fsQuad, fsQuadMat, denoiseQuad, denoiseMat }); this._updateRenderer(pathTracingRendererContainer); this._pathTracingRenderer = pathTracingRendererContainer; return pathTracingRendererContainer; } renderer(canvas, gl) { return this._pathTracingRenderer = this._pathTracingRenderer || this._createPathTracingRenderer(canvas, gl); } cook() { this._paramCallbackUpdate(); this.cookController.endCook(); } _updateRenderer(rendererContainer) { rendererContainer.update({ resolutionScale: this.pv.resolutionScale, displayDebug: this.pv.displayDebug, bounces: this.pv.bounces, transmissiveBounces: this.pv.transmissiveBounces, stableNoise: this.pv.stableNoise, filterGlossyFactor: this.pv.filterGlossyFactor, backgroundBlur: this.pv.backgroundBlur, environmentIntensity: this.pv.environmentIntensity, tiles: this.pv.tiles, multipleImportanceSampling: this.pv.multipleImportanceSampling, // denoise: this.pv.denoise, denoiseSigma: this.pv.denoiseSigma, denoiseThreshold: this.pv.denoiseThreshold, denoiseKSigma: this.pv.denoiseKSigma, // maxSamplesCount: this.pv.maxSamplesCount, samplesPerAnimationFrame: this.pv.samplesPerAnimationFrame, f: this.pv.f, useWorker: this.pv.useWorker }); } static PARAM_CALLBACK_generate(node) { node._paramCallbackGenerate(); } _paramCallbackGenerate() { var _a; const scene = this.scene().threejsScene(); (_a = this._pathTracingRenderer) == null ? void 0 : _a.generate(scene); } static PARAM_CALLBACK_update(node) { node._paramCallbackUpdate(); } _paramCallbackUpdate() { if (this._pathTracingRenderer) { this._updateRenderer(this._pathTracingRenderer); } } }