UNPKG

@polygonjs/polygonjs

Version:

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

130 lines (129 loc) 5.12 kB
"use strict"; import { NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending } from "three"; import { TypedMatNode } from "../_Base"; import { BaseController } from "./_BaseController"; import { NodeParamsConfig, ParamConfig } from "../../utils/params/ParamsConfig"; import { updateMaterialSideWithShadow, updateNodeSideWithShadow } from "./helpers/MaterialSideHelper"; const BLENDING_VALUES = { NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending }; const BLENDING_VALUE_NAMES = Object.keys(BLENDING_VALUES); export function AdvancedCommonParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); /** @param defines if the material is double sided or not */ this.doubleSided = ParamConfig.BOOLEAN(0); /** @param if the material is not double sided, it can be front sided, or back sided */ this.front = ParamConfig.BOOLEAN(1, { visibleIf: { doubleSided: false } }); /** @param override the default shadowSide behavior */ this.overrideShadowSide = ParamConfig.BOOLEAN(0); /** @param defines which side(s) are used when rendering shadows */ this.shadowDoubleSided = ParamConfig.BOOLEAN(0, { visibleIf: { overrideShadowSide: true } }); /** @param if the material is not double sided, it can be front sided, or back sided, when computing shadows */ this.shadowFront = ParamConfig.BOOLEAN(1, { visibleIf: { overrideShadowSide: true, shadowDoubleSided: false } }); /** @param defines if the objects using this material will be rendered in the color buffer. Setting it to false can have those objects occlude the ones behind */ this.colorWrite = ParamConfig.BOOLEAN(1, { separatorBefore: true, cook: false, callback: (node, param) => { AdvancedCommonController.update(node); } }); /** @param defines if the objects using this material will be rendered in the depth buffer. This can often help transparent objects */ this.depthWrite = ParamConfig.BOOLEAN(1, { cook: false, callback: (node, param) => { AdvancedCommonController.update(node); } }); /** @param toggle depth test */ this.depthTest = ParamConfig.BOOLEAN(1, { cook: false, callback: (node, param) => { AdvancedCommonController.update(node); } }); /** @param premultipliedAlpha */ this.premultipliedAlpha = ParamConfig.BOOLEAN(false, { separatorAfter: true }); /** @param blending */ this.blending = ParamConfig.INTEGER(NormalBlending, { menu: { entries: BLENDING_VALUE_NAMES.map((name) => { return { name, value: BLENDING_VALUES[name] }; }) } }); /** @param dithering, which can be useful when using postprocessing and banding appears on some objects */ this.dithering = ParamConfig.BOOLEAN(0); /** @param activate polygon offset */ this.polygonOffset = ParamConfig.BOOLEAN(false, { separatorBefore: true }); this.polygonOffsetFactor = ParamConfig.INTEGER(0, { range: [0, 1e3], visibleIf: { polygonOffset: 1 } }); this.polygonOffsetUnits = ParamConfig.INTEGER(0, { range: [0, 1e3], visibleIf: { polygonOffset: 1 } }); } }; } class AdvancedCommonParamsConfig extends AdvancedCommonParamConfig(NodeParamsConfig) { } class AdvancedCommonMapMatNode extends TypedMatNode { async material() { const container = await this.compute(); return container.material(); } } export class AdvancedCommonController extends BaseController { constructor(node) { super(node); this.node = node; } static async update(node) { const material = await node.material(); if (!material) { return; } node.controllers.advancedCommon.updateMaterial(material); } updateMaterial(material) { const pv = this.node.pv; updateMaterialSideWithShadow(material, pv); material.colorWrite = pv.colorWrite; material.depthWrite = pv.depthWrite; material.depthTest = pv.depthTest; material.blending = pv.blending; material.premultipliedAlpha = pv.premultipliedAlpha; material.dithering = pv.dithering; material.polygonOffset = pv.polygonOffset; if (material.polygonOffset) { material.polygonOffsetFactor = pv.polygonOffsetFactor; material.polygonOffsetUnits = pv.polygonOffsetUnits; material.needsUpdate = true; } } setParamsFromMaterial(material, record) { const p = this.node.p; updateNodeSideWithShadow(material, p); p.colorWrite.set(material.colorWrite); p.depthWrite.set(material.depthWrite); p.depthTest.set(material.depthTest); p.blending.set(material.blending); p.premultipliedAlpha.set(material.premultipliedAlpha); p.dithering.set(material.dithering); p.polygonOffset.set(material.polygonOffset); if (material.polygonOffset) { p.polygonOffsetFactor.set(material.polygonOffsetFactor); p.polygonOffsetUnits.set(material.polygonOffsetUnits); } } }