UNPKG

lume

Version:

Build next-level interactive web applications.

155 lines (140 loc) 4.71 kB
import 'element-behaviors' import {MeshStandardMaterial} from 'three/src/materials/MeshStandardMaterial.js' import {booleanAttribute, numberAttribute, stringAttribute} from '@lume/element' import {behavior} from '../../Behavior.js' import {receiver} from '../../PropReceiver.js' import {MaterialBehavior, type MaterialBehaviorAttributes} from './MaterialBehavior.js' export type StandardMaterialBehaviorAttributes = | MaterialBehaviorAttributes | 'alphaMap' | 'aoMap' | 'aoMapIntensity' | 'bumpMap' | 'bumpScale' | 'displacementMap' | 'displacementScale' | 'displacementBias' | 'texture' // map | 'normalMap' | 'normalScale' | 'metalness' | 'metalnessMap' | 'morphNormals' | 'morphTargets' | 'roughness' | 'roughnessMap' | 'vertexTangents' /** * @class StandardMaterialBehavior - * * A standard physically based material, using Metallic-Roughness workflow. * * Backed by Three.js [`THREE.MeshStandardMaterial`](https://threejs.org/docs/index.html#api/en/materials/MeshStandardMaterial) * * @extends MaterialBehavior */ export @behavior class StandardMaterialBehavior extends MaterialBehavior { @stringAttribute @receiver alphaMap = '' @stringAttribute @receiver aoMap = '' @numberAttribute @receiver aoMapIntensity = 1 @stringAttribute @receiver bumpMap = '' @numberAttribute @receiver bumpScale = 1 @stringAttribute @receiver displacementMap = '' @numberAttribute @receiver displacementScale = 1 @numberAttribute @receiver displacementBias = 0 // emissive?: Color | string | number; // envMap?: Texture | null; // @numberAttribute @receiver envMapIntensity?: number // @numberAttribute @receiver emissiveIntensity?: number // emissiveMap?: Texture | null; // lightMap?: Texture | null; // @numberAttribute @receiver lightMapIntensity?: number @stringAttribute @receiver texture = '' // map @stringAttribute @receiver normalMap = '' // normalMapType @numberAttribute @receiver normalScale = 1 @numberAttribute @receiver metalness = 0 @stringAttribute @receiver metalnessMap = '' // @numberAttribute @receiver refractionRatio?: number @numberAttribute @receiver roughness = 1 @stringAttribute @receiver roughnessMap = '' // wireframe?: boolean // @numberAttribute @receiver wireframeLinewidth?: number // Not supported because the WebGL line width is always 1. // @booleanAttribute @receiver skinning: boolean = false @booleanAttribute @receiver vertexTangents: boolean = false @booleanAttribute @receiver morphTargets: boolean = false @booleanAttribute @receiver morphNormals: boolean = false override _createComponent() { return new MeshStandardMaterial() } override connectedCallback() { super.connectedCallback() this.createEffect(() => { const mat = this.meshComponent if (!mat) return mat.aoMapIntensity = this.aoMapIntensity mat.bumpScale = this.bumpScale mat.displacementScale = this.displacementScale mat.displacementBias = this.displacementBias mat.normalScale.set(this.normalScale, this.normalScale) mat.metalness = this.metalness // mat.morphNormals = this.morphNormals // mat.morphTargets = this.morphTargets mat.roughness = this.roughness // mat.vertexTangents = this.vertexTangents // TODO Needed? // mat.needsUpdate = true this.element.needsUpdate() }) this._handleTexture( () => this.alphaMap, (mat, tex) => (mat.alphaMap = tex), mat => !!mat.alphaMap, ) this._handleTexture( () => this.aoMap, (mat, tex) => (mat.aoMap = tex), mat => !!mat.aoMap, ) this._handleTexture( () => this.bumpMap, (mat, tex) => (mat.bumpMap = tex), mat => !!mat.bumpMap, ) this._handleTexture( () => this.displacementMap, (mat, tex) => (mat.displacementMap = tex), mat => !!mat.displacementMap, ) this._handleTexture( () => this.texture, // map (mat, tex) => (mat.map = tex), mat => !!mat.map, () => {}, true, ) this._handleTexture( () => this.normalMap, (mat, tex) => (mat.normalMap = tex), mat => !!mat.normalMap, ) this._handleTexture( () => this.metalnessMap, (mat, tex) => (mat.metalnessMap = tex), mat => !!mat.metalnessMap, ) this._handleTexture( () => this.roughnessMap, (mat, tex) => (mat.roughnessMap = tex), mat => !!mat.roughnessMap, ) } } if (globalThis.window?.document && !elementBehaviors.has('standard-material')) elementBehaviors.define('standard-material', StandardMaterialBehavior) // This prevents errors with mixins. https://discord.com/channels/508357248330760243/508357248330760249/954526657312604180 export type MixinBaseClass<T> = T extends new (..._: any) => infer I ? {[K in keyof T]: T[K]} & (new (...args: any[]) => I) : new (...args: any[]) => T