UNPKG

@polygonjs/polygonjs

Version:

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

94 lines (84 loc) 3.55 kB
import {Constructor} from '../../../../types/GlobalTypes'; import {BaseController} from './_BaseController'; import {TypedMatNode} from '../_Base'; import {Material} from 'three'; import {ShaderMaterial} from 'three'; import {NodeParamsConfig, ParamConfig} from '../../utils/params/ParamsConfig'; import {CustomMaterialName, ShaderMaterialWithCustomMaterials} from '../../../../core/geometry/Material'; import {isBooleanTrue} from '../../../../core/BooleanValue'; import {ParamsValueAccessorType} from '../../utils/params/ParamsValueAccessor'; export interface UniformsTransparencyControllers { uniformTransparency: UniformsTransparencyController; } export function UniformsTransparencyParamConfig<TBase extends Constructor>(Base: TBase) { return class Mixin extends Base { /** @param sets the material to transparent */ transparent = ParamConfig.BOOLEAN(0); /** @param sets the material opacity */ opacity = ParamConfig.FLOAT(1); /** @param sets the min alpha below which the material is invisible */ alphaTest = ParamConfig.FLOAT(0); }; } type TransparencyMaterial = Material; // class TransparencyMaterial extends Material { // // transparent!: boolean; // // depthTest!: boolean; // // alphaTest!: number; // // uniforms!: IUniforms; // } class TransparencyParamsConfig extends UniformsTransparencyParamConfig(NodeParamsConfig) {} class TransparencyMatNode extends TypedMatNode<TransparencyMaterial, TransparencyParamsConfig> { async material() { const container = await this.compute(); return container.material() as TransparencyMaterial | undefined; } controllers!: UniformsTransparencyControllers; } export class UniformsTransparencyController extends BaseController { constructor(protected override node: TransparencyMatNode) { super(node); } static async update(node: TransparencyMatNode) { const material = await node.material(); if (!material) { return; } node.controllers.uniformTransparency.updateMaterial(material); } override updateMaterial(material: TransparencyMaterial) { const pv = this.node.pv; this._updateTransparency(material, pv); } private _updateTransparency(mat: TransparencyMaterial, pv: ParamsValueAccessorType<TransparencyParamsConfig>) { // transparent is currently only changed for the main material, // not for the customMaterials, // as that currently makes them disappear. // Also, we do not use the alternative condition || pv.opacity < 1; // to set a material transparent, as this can be useful to have those params independent, // especially for shadow materials mat.transparent = isBooleanTrue(pv.transparent); this._updateCommon(mat, pv); } private _updateCommon(mat: TransparencyMaterial, pv: ParamsValueAccessorType<TransparencyParamsConfig>) { const shaderMaterial = mat as ShaderMaterial; if (shaderMaterial.uniforms && shaderMaterial.uniforms.opacity) { shaderMaterial.uniforms.opacity.value = pv.opacity; } mat.opacity = pv.opacity; if (shaderMaterial.uniforms && shaderMaterial.uniforms.alphaTest) { shaderMaterial.uniforms.alphaTest.value = pv.alphaTest; } mat.alphaTest = pv.alphaTest; const customMaterials = (mat as ShaderMaterialWithCustomMaterials).customMaterials; if (customMaterials) { const customNames: CustomMaterialName[] = Object.keys(customMaterials) as CustomMaterialName[]; for (const customName of customNames) { const customMaterial = customMaterials[customName]; if (customMaterial) { this._updateCommon(customMaterial as ShaderMaterial, pv); } } } } }