UNPKG

threepipe

Version:

A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.

377 lines (330 loc) 12 kB
import { BufferGeometry, Camera, Color, Event, IUniform, Material, MaterialEventMap, MaterialParameters, Object3D, Scene, Texture, WebGLProgramParametersWithUniforms, WebGLRenderer, } from 'three' import {IDisposable, IJSONSerializable} from 'ts-browser-helpers' import type {MaterialExtension} from '../materials' import type {ChangeEvent, IUiConfigContainer} from 'uiconfig.js' import type {SerializationMetaType} from '../utils' import {AnimateTime} from '../utils' import type {IObject3D} from './IObject' import {ISetDirtyCommonOptions} from './IObject' import type {ITexture} from './ITexture' import type {IImportResultUserData} from '../assetmanager' export type IMaterialParameters = MaterialParameters & {customMaterialExtensions?: MaterialExtension[]} // export type IMaterialEventTypes = 'dispose' | 'materialUpdate' | 'beforeRender' | 'beforeCompile' | 'afterRender' | 'textureUpdate' | 'beforeDeserialize' // export type IMaterialEvent<T extends string = IMaterialEventTypes> = Event & { // type: T // bubbleToObject?: boolean // bubbleToParent?: boolean // material?: IMaterial // // texture?: ITexture // oldTexture?: ITexture // // uiChangeEvent?: ChangeEvent // } export interface IMaterialEventMap extends MaterialEventMap{ beforeCompile: { shader: WebGLProgramParametersWithUniforms renderer: WebGLRenderer } beforeRender: { renderer: WebGLRenderer scene: Scene camera: Camera geometry: BufferGeometry object: Object3D } afterRender: { renderer: WebGLRenderer scene: Scene camera: Camera geometry: BufferGeometry object: Object3D } /** * Fires when the material is set/added to a mesh * This is applicable of all types of Object3D, like Line etc, not just Mesh */ addToMesh: { object: Object3D } /** * Fires when the material is changed/removed to a mesh * This is applicable of all types of Object3D, like Line etc, not just Mesh */ removeFromMesh: { object: Object3D } /** * For internal use */ beforeDeserialize: { data: unknown meta?: SerializationMetaType bubbleToObject: boolean bubbleToParent: boolean } texturesChanged: { textures: Set<ITexture> oldTextures: Set<ITexture> addedTextures: Set<ITexture> removedTextures: Set<ITexture> material: IMaterial bubbleToObject?: boolean bubbleToParent?: boolean } } declare module 'three'{ export interface MaterialEventMap{ materialUpdate: { // These are handled in dispatchEvent override in iMaterialCommons bubbleToObject?: boolean bubbleToParent?: boolean uiChangeEvent?: ChangeEvent } & IMaterialSetDirtyOptions textureUpdate: { texture: ITexture bubbleToObject?: boolean bubbleToParent?: boolean uiChangeEvent?: ChangeEvent } select: { // todo remove? ui?: boolean // focusCamera?: boolean // todo ? bubbleToObject?: boolean bubbleToParent?: boolean material: IMaterial value?: /* IObject3D | */ IMaterial | null // todo is this required? source?: string // who is triggering the event. so that recursive events can be prevented } /* & IObjectSetDirtyOptions*/ } } export interface IMaterialSetDirtyOptions extends ISetDirtyCommonOptions{ /** * @default true */ bubbleToObject?: boolean, /** * @default true */ needsUpdate?: boolean, /** * Change identifier that triggered the `setDirty` call. * This is different from `key` in that it is used to identify the property/key that is changed. In many cases these could be same, but they could also be different eg, key might be x, with change being position. */ change?: string | keyof IMaterial [key: string]: any } export interface IMaterialUserData extends IImportResultUserData{ uuid?: string // adding to userdata also, so that its saved in gltf /** * Automatically dispose material when not used by any object in the scene * @default true */ disposeOnIdle?: boolean renderToGBuffer?: boolean /** * Same as {@link renderToGBuffer} but for depth only, not normal or flags etc */ renderToDepth?: boolean /** * Flag to tell the scene to prefer `material.envMapIntensity` over `scene.environmentIntensity` * only for materials that have envMapIntensity */ separateEnvMapIntensity?: boolean // default: false /** * The environment map to use in the `RootScene`. To use this, object with the material must be in the RootScene, and the key should exist in the `RootScene`'s `textureSlots`. * * only for materials that have envMap */ envMapSlotKey?: string /** * Automatically register this material in the {@link MaterialManager} when added to the scene. * This provides hook to other plugins to extend the material, add uiconfig etc. * @default true */ autoRegisterInManager?: boolean cloneId?: string cloneCount?: number __isVariation?: boolean inverseAlphaMap?: boolean // only for physical material right now /** * See {@link MaterialManager.dispose} as {@link BaseGroundPlugin._refreshMaterial} */ runtimeMaterial?: boolean /** * See {@link GBufferPlugin} */ gBufferData?: { materialId?: number /** * @default true */ tonemapEnabled?: boolean [key: string]: any } /** * Force a depth value in GBuffer. * This is useful to force center values like 0 to the depth. */ forcedLinearDepth?: number /** * General flag to disable multiple plugins on the material at once, like SSAO, SSR, Bloom etc. */ pluginsDisabled?: boolean // todo uiconfig for this in imaterial? // todo: move these to respective plugins /** * For SSCSPlugin */ sscsDisabled?: boolean /** * For SSRPlugin */ ssreflDisabled?: boolean /** * For SSRPlugin */ ssreflNonPhysical?: boolean /** * List of properties that will be saved in the glb/material files when this material is saved. * The other properties are expected to be loaded/filled at runtime by default values or from an external material loaded from {@link IImportResultUserData.rootPath}. */ sProperties?: string[] /** * If this is a placeholder/dummy material. These materials are not saved in asset/glTF files. */ isPlaceholder?: boolean // todo comment and check [key: string]: any // legacy, to be removed /** * @deprecated */ setDirty?: (options?: IMaterialSetDirtyOptions) => void /** * @deprecated Use {@link postTonemap.tonemapEnabled} instead. This is kept because used in old files. */ postTonemap?: boolean } export interface AnimateTimeMaterial extends AnimateTime{from?: IMaterial} export interface IMaterial<TE extends IMaterialEventMap = IMaterialEventMap> extends Material<TE>, IJSONSerializable<any, SerializationMetaType>, IDisposable, IUiConfigContainer { constructor: { TYPE: string TypeSlug: string TypeAlias?: string[] MaterialProperties?: Record<string, any> MapProperties?: string[] InterpolateProperties?: string[] new(...args: any[]): IMaterial } assetType: 'material' setDirty(options?: IMaterialSetDirtyOptions): void; // clone?: ()=> any; needsUpdate: boolean; // toJSON same as three.js Material.toJSON // toJSON(meta?: any): any; // copyProps should be just setValues /** * * @param parameters - An existing `Material` object or a plain JavaScript object with properties that will be copied to the material. * @param allowInvalidType - Copy properties even if the type is different. Not used by default, but implemented in some material classes. * @param clearCurrentUserData - clears the userData instead of merging first level. Default - true if `Material` object is passed, false if parameters object is passed * @param time - parameters to animate the setting of properties */ setValues(parameters: Material|(MaterialParameters&{type?:string}), allowInvalidType?: boolean, clearCurrentUserData?: boolean, time?: AnimateTimeMaterial): void; toJSON(meta?: SerializationMetaType, _internal?: boolean): any; fromJSON(json: any, meta?: SerializationMetaType, _internal?: boolean): /* this*/ any | null; extraUniformsToUpload: Record<string, IUniform> materialExtensions: MaterialExtension[] registerMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; unregisterMaterialExtensions: (customMaterialExtensions: MaterialExtension[]) => void; /** * Objects in the scene that are using this material. * This is set in the {@link Object3DManager} when the objects are added/removed from the scene. Do not modify this set directly. */ appliedMeshes: Set<IObject3D> lastShader?: WebGLProgramParametersWithUniforms // Note: for userData: add _ in front of for private use, which is preserved while cloning but not serialisation, and __ for private use, which is not preserved while cloning and serialisation userData: IMaterialUserData /** * Disposes the material from the GPU. * Set force to false if not sure the material is used by any object in the scene. * // todo add check for visible in scene also? or is that overkill * @param force - when true, same as three.js dispose. when false, only disposes if disposeOnIdle not false and not used by any object in the scene. default: true */ dispose(force?: boolean): void /** * Clones the Material. * This is a shallow clone, so the properties are copied by reference. * * @param track - if true, the clone id and count will be tracked in the userData and a suffix will be appended to the name. default - false */ clone(track?: boolean): /* this*/ any /** * A promise can be set by the object to indicate that the material(or any of its properties) is loading. * This can be used by the scene, viewer, plugins to defer actions until the material is loaded. */ _loadingPromise?: Promise<void|any> // optional from subclasses, added here for autocomplete color?: Color wireframe?: boolean flatShading?: boolean map?: ITexture | null alphaMap?: ITexture | null envMap?: ITexture | null envMapIntensity?: number aoMap?: ITexture | null lightMap?: ITexture | null normalMap?: ITexture | null bumpMap?: ITexture | null displacementMap?: ITexture | null aoMapIntensity?: number lightMapIntensity?: number roughnessMap?: ITexture | null metalnessMap?: ITexture | null roughness?: number metalness?: number transmissionMap?: ITexture | null transmission?: number emissiveMap?: ITexture | null emissiveIntensity?: number emissive?: Color linewidth?: number isRawShaderMaterial?: boolean isPhysicalMaterial?: boolean isLineMaterial?: boolean isLineBasicMaterial?: boolean isUnlitMaterial?: boolean isGBufferMaterial?: boolean isLineMaterial2?: boolean isUnlitLineMaterial?: boolean // [key: string]: any // private /** * @internal */ ['__textureUpdate']?: (e: Event<'update', Texture>)=>void /** * @internal */ ['_mapRefs']?: Set<ITexture> } declare module 'three'{ // todo add to three-ts-types interface IUniform{ needsUpdate?: boolean } }