@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
248 lines (247 loc) • 8.3 kB
JavaScript
"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);
}
}
}