UNPKG

@polygonjs/polygonjs

Version:

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

140 lines (132 loc) 5.4 kB
import {Constructor} from '../../../../types/GlobalTypes'; import { Material, Blending, NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, } from 'three'; import {TypedMatNode} from '../_Base'; import {BaseController, SetParamsTextureNodesRecord} from './_BaseController'; import {NodeParamsConfig, ParamConfig} from '../../utils/params/ParamsConfig'; import {BaseNodeType} from '../../_Base'; import {BaseParamType} from '../../../params/_Base'; 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<TBase extends Constructor>(Base: TBase) { return class Mixin extends Base { /** @param defines if the material is double sided or not */ doubleSided = ParamConfig.BOOLEAN(0); /** @param if the material is not double sided, it can be front sided, or back sided */ front = ParamConfig.BOOLEAN(1, {visibleIf: {doubleSided: false}}); /** @param override the default shadowSide behavior */ overrideShadowSide = ParamConfig.BOOLEAN(0); /** @param defines which side(s) are used when rendering shadows */ 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 */ 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 */ colorWrite = ParamConfig.BOOLEAN(1, { separatorBefore: true, cook: false, callback: (node: BaseNodeType, param: BaseParamType) => { AdvancedCommonController.update(node as AdvancedCommonMapMatNode); }, }); /** @param defines if the objects using this material will be rendered in the depth buffer. This can often help transparent objects */ depthWrite = ParamConfig.BOOLEAN(1, { cook: false, callback: (node: BaseNodeType, param: BaseParamType) => { AdvancedCommonController.update(node as AdvancedCommonMapMatNode); }, }); /** @param toggle depth test */ depthTest = ParamConfig.BOOLEAN(1, { cook: false, callback: (node: BaseNodeType, param: BaseParamType) => { AdvancedCommonController.update(node as AdvancedCommonMapMatNode); }, }); /** @param premultipliedAlpha */ premultipliedAlpha = ParamConfig.BOOLEAN(false, { separatorAfter: true, }); /** @param blending */ blending = ParamConfig.INTEGER(NormalBlending, { menu: { entries: BLENDING_VALUE_NAMES.map((name) => { return {name: name, value: (BLENDING_VALUES as any)[name]}; }), }, }); /** @param dithering, which can be useful when using postprocessing and banding appears on some objects */ dithering = ParamConfig.BOOLEAN(0); /** @param activate polygon offset */ polygonOffset = ParamConfig.BOOLEAN(false, {separatorBefore: true}); polygonOffsetFactor = ParamConfig.INTEGER(0, {range: [0, 1000], visibleIf: {polygonOffset: 1}}); polygonOffsetUnits = ParamConfig.INTEGER(0, {range: [0, 1000], visibleIf: {polygonOffset: 1}}); }; } class AdvancedCommonParamsConfig extends AdvancedCommonParamConfig(NodeParamsConfig) {} export interface AdvancedCommonControllers { advancedCommon: AdvancedCommonController; } abstract class AdvancedCommonMapMatNode extends TypedMatNode<Material, AdvancedCommonParamsConfig> { controllers!: AdvancedCommonControllers; async material() { const container = await this.compute(); return container.material() as Material | undefined; } } export class AdvancedCommonController extends BaseController { constructor(protected override node: AdvancedCommonMapMatNode) { super(node); } static async update(node: AdvancedCommonMapMatNode) { const material = await node.material(); if (!material) { return; } node.controllers.advancedCommon.updateMaterial(material); } override updateMaterial(material: 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 as 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; } } override setParamsFromMaterial(material: Material, record: SetParamsTextureNodesRecord) { 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); } } }