UNPKG

@polygonjs/polygonjs

Version:

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

109 lines (105 loc) 3.98 kB
import {Constructor} from '../../../../types/GlobalTypes'; import {TypedMatNode} from '../_Base'; import {BaseTextureMapController, BooleanParamOptions, NodePathOptions} from './_BaseTextureController'; import {NodeParamsConfig, ParamConfig} from '../../utils/params/ParamsConfig'; import { Material, MeshMatcapMaterial, MeshPhongMaterial, MeshStandardMaterial, MeshPhysicalMaterial, MeshNormalMaterial, MeshToonMaterial, } from 'three'; import {MaterialTexturesRecord, SetParamsTextureNodesRecord} from './_BaseController'; export function DisplacementMapParamConfig<TBase extends Constructor>(Base: TBase) { return class Mixin extends Base { /** @param toggle if you want to use a displacement map */ useDisplacementMap = ParamConfig.BOOLEAN(0, { separatorBefore: true, ...BooleanParamOptions(TextureDisplacementMapController), }); /** @param specify the displacement map COP node */ displacementMap = ParamConfig.NODE_PATH( '', NodePathOptions(TextureDisplacementMapController, 'useDisplacementMap') ); /** @param displacement scale */ displacementScale = ParamConfig.FLOAT(1, { range: [0, 1], rangeLocked: [false, false], ...NodePathOptions(TextureDisplacementMapController, 'useDisplacementMap'), }); /** @param displacement bias */ displacementBias = ParamConfig.FLOAT(0, { range: [0, 1], rangeLocked: [false, false], ...NodePathOptions(TextureDisplacementMapController, 'useDisplacementMap'), }); }; } type TextureDisplacementMapControllerCurrentMaterial = | MeshMatcapMaterial | MeshNormalMaterial | MeshStandardMaterial | MeshPhysicalMaterial | MeshToonMaterial | MeshPhongMaterial; function _isValidMaterial(material?: Material): material is TextureDisplacementMapControllerCurrentMaterial { if (!material) { return false; } return (material as MeshMatcapMaterial).displacementScale != null; } class TextureDisplacementMapParamsConfig extends DisplacementMapParamConfig(NodeParamsConfig) {} export interface TextureDisplacementMapControllers { displacementMap: TextureDisplacementMapController; } abstract class TextureDisplacementMapMatNode extends TypedMatNode< TextureDisplacementMapControllerCurrentMaterial, TextureDisplacementMapParamsConfig > { controllers!: TextureDisplacementMapControllers; async material() { const container = await this.compute(); return container.material() as TextureDisplacementMapControllerCurrentMaterial | undefined; } } export class TextureDisplacementMapController extends BaseTextureMapController { constructor(protected override node: TextureDisplacementMapMatNode) { super(node); } override initializeNode() { this.add_hooks(this.node.p.useDisplacementMap, this.node.p.displacementMap); } static override async update(node: TextureDisplacementMapMatNode) { node.controllers.displacementMap.update(); } override async update() { const material = await this.node.material(); if (!_isValidMaterial(material)) { return; } await this.updateMaterial(material); } override async updateMaterial(material: TextureDisplacementMapControllerCurrentMaterial) { await this._update(material, 'displacementMap', this.node.p.useDisplacementMap, this.node.p.displacementMap); material.displacementScale = this.node.pv.displacementScale; material.displacementBias = this.node.pv.displacementBias; } override getTextures(material: TextureDisplacementMapControllerCurrentMaterial, record: MaterialTexturesRecord) { record.set('displacementMap', material.displacementMap); } override setParamsFromMaterial( material: TextureDisplacementMapControllerCurrentMaterial, record: SetParamsTextureNodesRecord ) { const mapNode = record.get('emissiveMap'); this.node.p.useDisplacementMap.set(mapNode != null); if (mapNode) { this.node.p.displacementMap.setNode(mapNode, {relative: true}); } this.node.p.displacementScale.set(material.displacementScale); this.node.p.displacementBias.set(material.displacementBias); } }