UNPKG

@polygonjs/polygonjs

Version:

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

103 lines (102 loc) 3.43 kB
"use strict"; import { TypedMatNode } from "../_Base"; import { BaseController } from "./_BaseController"; import { NodeParamsConfig, ParamConfig } from "../../utils/params/ParamsConfig"; import { isBooleanTrue } from "../../../../core/BooleanValue"; import PCSS from "./shadows/pcss/glsl/PCSS.glsl"; import PCSSGetShadow from "./shadows/pcss/glsl/PCSSGetShadow.glsl"; import SHADOW_MAP_PARS_FRAGMENT from "three/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl"; import { ThreeToGl } from "../../../../core/ThreeToGl"; export function PCSSParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); /** @param if on, the material will blur shadows cast on this object. Note that you should adjust the near parameter of the light shadow to get the result visible */ this.shadowPCSS = ParamConfig.BOOLEAN(0, { callback: (node) => { PCSSController.PARAM_CALLBACK_setRecompileRequired(node); }, separatorBefore: true }); /** @param shadowPCSSFilterSize PCSS Shadow filter size */ this.shadowPCSSFilterSize = ParamConfig.FLOAT(1, { visibleIf: { shadowPCSS: 1 }, range: [0, 10], rangeLocked: [true, false] }); } }; } class PCSSParamsConfig extends PCSSParamConfig(NodeParamsConfig) { } function isValidMaterial(material) { if (!material) { return false; } return true; } class PCSSMapMatNode extends TypedMatNode { async material() { const container = await this.compute(); return container.material(); } } export class PCSSController extends BaseController { constructor(node) { super(node); this.node = node; } static filterFragmentShader(node, fragmentShader) { const PCSSWithDefines = ` #define PCSS_FILTER_SIZE ${ThreeToGl.float(node.pv.shadowPCSSFilterSize)} ${PCSS} `; let shadowParsFragmentModified = SHADOW_MAP_PARS_FRAGMENT; shadowParsFragmentModified = shadowParsFragmentModified.replace( "#ifdef USE_SHADOWMAP", `#ifdef USE_SHADOWMAP ${PCSSWithDefines} ` ); shadowParsFragmentModified = shadowParsFragmentModified.replace( "#if defined( SHADOWMAP_TYPE_PCF )", ` ${PCSSGetShadow} #if defined( SHADOWMAP_TYPE_PCF )` ); fragmentShader = fragmentShader.replace("#include <shadowmap_pars_fragment>", shadowParsFragmentModified); return fragmentShader; } static async update(node) { const material = await node.material(); if (!isValidMaterial(material)) { return; } node.controllers.PCSS.updateMaterial(material); } async update() { PCSSController.update(this.node); } updateMaterial(material) { var _a, _b; const matNode = this.node; if (!matNode.assemblerController) { return; } const callbackName = "PCSS"; if (isBooleanTrue(this.node.pv.shadowPCSS)) { (_a = matNode.assemblerController()) == null ? void 0 : _a.addFilterFragmentShaderCallback( callbackName, (fragmentShader) => PCSSController.filterFragmentShader(this.node, fragmentShader) ); } else { (_b = matNode.assemblerController()) == null ? void 0 : _b.removeFilterFragmentShaderCallback(callbackName); } } // static async update(node: PCSSMapMatNode) { // node.controllers.PCSS.update(); // } static PARAM_CALLBACK_setRecompileRequired(node) { node.controllers.PCSS.update(); } }