@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
94 lines (89 loc) • 3.33 kB
text/typescript
import {Constructor} from '../../../../types/GlobalTypes';
import {TypedMatNode} from '../_Base';
import {BaseTextureMapController, BooleanParamOptions, NodePathOptions} from './_BaseTextureController';
import {NodeParamsConfig, ParamConfig} from '../../utils/params/ParamsConfig';
import {
Material,
MeshBasicMaterial,
MeshPhongMaterial,
MeshLambertMaterial,
MeshStandardMaterial,
MeshPhysicalMaterial,
MeshToonMaterial,
} from 'three';
import {MaterialTexturesRecord, SetParamsTextureNodesRecord} from './_BaseController';
export function LightMapParamConfig<TBase extends Constructor>(Base: TBase) {
return class Mixin extends Base {
/** @param toggle if you want to use a light map */
useLightMap = ParamConfig.BOOLEAN(0, {
separatorBefore: true,
...BooleanParamOptions(TextureLightMapController),
});
/** @param specify the light map COP node */
lightMap = ParamConfig.NODE_PATH('', NodePathOptions(TextureLightMapController, 'useLightMap'));
/** @param light. When set to 0, reflections from environment maps will be very sharp, or blurred when 1. Any value between 0 and 1 can help modulate this. */
lightMapIntensity = ParamConfig.FLOAT(1, {
visibleIf: {useLightMap: 1},
});
};
}
type TextureLightMapCurrentMaterial =
| MeshBasicMaterial
| MeshLambertMaterial
| MeshStandardMaterial
| MeshPhysicalMaterial
| MeshToonMaterial
| MeshPhongMaterial;
function _isValidMaterial(material?: Material): material is TextureLightMapCurrentMaterial {
if (!material) {
return false;
}
return (material as MeshBasicMaterial).lightMapIntensity != null;
}
class TextureLightMapParamsConfig extends LightMapParamConfig(NodeParamsConfig) {}
export interface TextureLightMapControllers {
lightMap: TextureLightMapController;
}
abstract class TextureLightMapMatNode extends TypedMatNode<
TextureLightMapCurrentMaterial,
TextureLightMapParamsConfig
> {
controllers!: TextureLightMapControllers;
async material() {
const container = await this.compute();
return container.material() as TextureLightMapCurrentMaterial | undefined;
}
}
export class TextureLightMapController extends BaseTextureMapController {
constructor(protected override node: TextureLightMapMatNode) {
super(node);
}
override initializeNode() {
this.add_hooks(this.node.p.useLightMap, this.node.p.lightMap);
}
static override async update(node: TextureLightMapMatNode) {
node.controllers.lightMap.update();
}
override async update() {
const material = await this.node.material();
if (!_isValidMaterial(material)) {
return;
}
await this.updateMaterial(material);
}
override async updateMaterial(material: TextureLightMapCurrentMaterial) {
await this._update(material, 'lightMap', this.node.p.useLightMap, this.node.p.lightMap);
material.lightMapIntensity = this.node.pv.lightMapIntensity;
}
override getTextures(material: TextureLightMapCurrentMaterial, record: MaterialTexturesRecord) {
record.set('lightMap', material.lightMap);
}
override setParamsFromMaterial(material: TextureLightMapCurrentMaterial, record: SetParamsTextureNodesRecord) {
const mapNode = record.get('lightMap');
this.node.p.useLightMap.set(mapNode != null);
if (mapNode) {
this.node.p.lightMap.setNode(mapNode, {relative: true});
}
this.node.p.lightMapIntensity.set(material.lightMapIntensity);
}
}