Преглед изворни кода

Add defaultFragment.glsl, ObjectShaderMaterial.ts

master
Palash Bansal пре 1 година
родитељ
комит
ba982a3058
No account linked to committer's email address

+ 1
- 0
src/core/index.ts Прегледај датотеку

@@ -3,6 +3,7 @@ export {CameraView, type ICameraView} from './camera/CameraView'
export {ExtendedShaderMaterial} from './material/ExtendedShaderMaterial'
export {PhysicalMaterial, type PhysicalMaterialEventTypes, MeshStandardMaterial2} from './material/PhysicalMaterial'
export {ShaderMaterial2} from './material/ShaderMaterial2'
export {ObjectShaderMaterial, type ObjectShaderMaterialEventTypes} from './material/ObjectShaderMaterial'
export {UnlitMaterial, type UnlitMaterialEventTypes, MeshBasicMaterial2} from './material/UnlitMaterial'
export {UnlitLineMaterial, type UnlitLineMaterialEventTypes, LineBasicMaterial2} from './material/UnlitLineMaterial'
export {LineMaterial2, type LineMaterial2EventTypes} from './material/LineMaterial2'

+ 5
- 0
src/core/material/LineMaterial2.ts Прегледај датотеку

@@ -17,6 +17,11 @@ import {LineMaterial, type LineMaterialParameters} from 'three/examples/jsm/line

export type LineMaterial2EventTypes = IMaterialEventTypes | ''

/**
* And extension of three.js LineMaterial that can be assigned to lines, and support threepipe features, uiconfig, and serialization.
*
* @category Materials
*/
export class LineMaterial2 extends LineMaterial<IMaterialEvent, LineMaterial2EventTypes> implements IMaterial<IMaterialEvent, LineMaterial2EventTypes> {
declare ['constructor']: typeof LineMaterial2
public static readonly TypeSlug = 'lmat'

+ 239
- 0
src/core/material/ObjectShaderMaterial.ts Прегледај датотеку

@@ -0,0 +1,239 @@
import {IUniform, Material, Shader, ShaderMaterial, ShaderMaterialParameters, WebGLRenderer} from 'three'
import {generateUiConfig, UiObjectConfig} from 'uiconfig.js'
import {
IMaterial,
IMaterialEvent,
IMaterialEventTypes,
IMaterialGenerator,
IMaterialParameters,
IMaterialTemplate,
IMaterialUserData,
} from '../IMaterial'
import {MaterialExtension} from '../../materials'
import {SerializationMetaType, shaderUtils, ThreeSerialization} from '../../utils'
import {iMaterialCommons, threeMaterialPropList} from './iMaterialCommons'
import {IObject3D} from '../IObject'
import {iMaterialUI} from './IMaterialUi'

export type ObjectShaderMaterialEventTypes = IMaterialEventTypes | ''

/**
* And extension of three.js ShaderMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization.
*
* @category Materials
*/
export class ObjectShaderMaterial extends ShaderMaterial<IMaterialEvent, ObjectShaderMaterialEventTypes> implements IMaterial<IMaterialEvent, ObjectShaderMaterialEventTypes> {
declare ['constructor']: typeof ObjectShaderMaterial

public static readonly TypeSlug = 'shmat'
public static readonly TYPE = 'ObjectShaderMaterial' // not using .type because it is used by three.js
assetType = 'material' as const

declare userData: IMaterialUserData

public readonly isObjectShaderMaterial = true

readonly appliedMeshes: Set<IObject3D> = new Set()
readonly setDirty = iMaterialCommons.setDirty
dispose(): this {return iMaterialCommons.dispose(super.dispose).call(this)}
clone(): this {return iMaterialCommons.clone(super.clone).call(this)}
dispatchEvent(event: IMaterialEvent): void {iMaterialCommons.dispatchEvent(super.dispatchEvent).call(this, event)}

generator?: IMaterialGenerator

// envMap: ITexture | null = null

constructor({customMaterialExtensions, ...parameters}: ShaderMaterialParameters & IMaterialParameters = {}) {
super()
!this.defines && (this.defines = {})
this.fog = false
this.setDirty = this.setDirty.bind(this)
if (customMaterialExtensions) this.registerMaterialExtensions(customMaterialExtensions)
iMaterialCommons.upgradeMaterial.call(this)
this.setValues(parameters)
}

// region Material Extension

materialExtensions: MaterialExtension[] = []
extraUniformsToUpload: Record<string, IUniform> = {}
registerMaterialExtensions = iMaterialCommons.registerMaterialExtensions
unregisterMaterialExtensions = iMaterialCommons.unregisterMaterialExtensions

customProgramCacheKey(): string {
return super.customProgramCacheKey() + iMaterialCommons.customProgramCacheKey.call(this)
}

onBeforeCompile(shader: Shader, renderer: WebGLRenderer): void { // shader is not Shader but WebglUniforms.getParameters return value type so includes defines
// const f = [
// ['vec3 outgoingLight = ', 'afterModulation'], // added markers before found substring
// ['#include <aomap_fragment>', 'beforeModulation'],
// ['ReflectedLight reflectedLight = ', 'beforeAccumulation'],
// ['#include <clipping_planes_fragment>', 'mainStart'],
// ]
// const v = [
// ['#include <uv_vertex>', 'mainStart'],
// ]
//
// for (const vElement of v) shader.vertexShader = shaderReplaceString(shader.vertexShader, vElement[0], '#glMarker ' + vElement[1] + '\n' + vElement[0])
// for (const vElement of f) shader.fragmentShader = shaderReplaceString(shader.fragmentShader, vElement[0], '#glMarker ' + vElement[1] + '\n' + vElement[0])

iMaterialCommons.onBeforeCompile.call(this, shader, renderer)
// shader.defines.INVERSE_ALPHAMAP = this.userData.inverseAlphaMap ? 1 : 0

super.onBeforeCompile(shader, renderer)
}

// onBeforeRender(...args: Parameters<IMaterial['onBeforeRender']>): void {
// super.onBeforeRender(...args)
// iMaterialCommons.onBeforeRender.call(this, ...args)
// }
onBeforeRender = iMaterialCommons.onBeforeRenderOverride(super.onBeforeRender)
onAfterRender = iMaterialCommons.onAfterRenderOverride(super.onAfterRender)

// endregion

// region Serialization

/**
* Sets the values of this material based on the values of the passed material or an object with material properties
* The input is expected to be a valid material or a deserialized material parameters object(including the deserialized userdata)
* @param parameters - material or material parameters object
* @param allowInvalidType - if true, the type of the oldMaterial is not checked. Objects without type are always allowed.
* @param clearCurrentUserData - if undefined, then depends on material.isMaterial. if true, the current userdata is cleared before setting the new values, because it can have data which wont be overwritten if not present in the new material.
*/
setValues(parameters: Material|(ShaderMaterialParameters&{type?:string}), allowInvalidType = true, clearCurrentUserData: boolean|undefined = undefined): this {
if (!parameters) return this
if (parameters.type && !allowInvalidType && !['ShaderMaterial', 'ShaderMaterial2', 'ExtendedShaderMaterial', this.constructor.TYPE].includes(parameters.type)) {
console.error('Material type is not supported:', parameters.type)
return this
}
if (clearCurrentUserData === undefined) clearCurrentUserData = (<Material>parameters).isMaterial
if (clearCurrentUserData) this.userData = {}
iMaterialCommons.setValues(super.setValues).call(this, parameters)

this.userData.uuid = this.uuid
return this
}
copy(source: Material|any): this {
return this.setValues(source, false)
}

/**
* Serializes this material to JSON.
* @param meta - metadata for serialization
* @param _internal - Calls only super.toJSON, does internal three.js serialization and `@serialize` tags. Set it to true only if you know what you are doing. This is used in Serialization->serializer->material
*/
toJSON(meta?: SerializationMetaType, _internal = false): any {
if (_internal) return {
...super.toJSON(meta),
...ThreeSerialization.Serialize(this, meta, true), // this will serialize the properties of this class(like defined with @serialize and @serialize attribute)
}
return ThreeSerialization.Serialize(this, meta, false) // this will call toJSON again, but with baseOnly=true, that's why we set isThis to false.
}

/**
* Deserializes the material from JSON.
* Textures should be loaded and in meta.textures before calling this method.
* todo - needs to be tested
* @param data
* @param meta
* @param _internal
*/
fromJSON(data: any, meta?: SerializationMetaType, _internal = false): this | null {
if (_internal) {
ThreeSerialization.Deserialize(data, this, meta, true)
return this.setValues(data)
}
this.dispatchEvent({type: 'beforeDeserialize', data, meta, bubbleToObject: true, bubbleToParent: true})
return this
}

// endregion

// region UI Config

// todo dispose ui config
uiConfig: UiObjectConfig = {
type: 'folder',
label: 'Shader Material',
uuid: 'OSM2_' + this.uuid,
expanded: true,
onChange: (ev)=>{
if (!ev.config || ev.config.onChange) return
// todo set needsUpdate true only for properties that require it like maps.
this.setDirty({uiChangeEvent: ev, needsUpdate: !!ev.last, refreshUi: !!ev.last})
},
children: [
...generateUiConfig(this),
...iMaterialUI.base(this),
iMaterialUI.blending(this),
iMaterialUI.polygonOffset(this),
...iMaterialUI.misc(this),
],
}

// endregion UI Config


// Class properties can also be listed with annotations like @serialize or @property
// used for serialization // todo change for shadermaterial
static readonly MaterialProperties = {
...threeMaterialPropList,

defines: {},
uniforms: {},
uniformsGroups: [],

vertexShader: '',
fragmentShader: '',

linewidth: 1,

wireframe: false,
wireframeLinewidth: 1,

fog: false, // set to use scene fog
lights: false, // set to use scene lights
clipping: false, // set to use user-defined clipping planes

forceSinglePass: true,

extensions: {
derivatives: false, // set to use derivatives
fragDepth: false, // set to use fragment depth values
drawBuffers: false, // set to use draw buffers
shaderTextureLOD: false, // set to use shader texture LOD
},

// When rendered geometry doesn't include these attributes but the material does,
// use these default values in WebGL. This avoids errors when buffer data is missing.
defaultAttributeValues: {
'color': [1, 1, 1],
'uv': [0, 0],
'uv1': [0, 0],
},

index0AttributeName: undefined,
uniformsNeedUpdate: false,

glslVersion: null,
flatShading: false,
}

static MaterialTemplate: IMaterialTemplate<ObjectShaderMaterial, Partial<typeof ObjectShaderMaterial.MaterialProperties>> = {
materialType: ObjectShaderMaterial.TYPE,
name: 'shader',
typeSlug: ObjectShaderMaterial.TypeSlug,
alias: ['shader', ObjectShaderMaterial.TYPE, ObjectShaderMaterial.TypeSlug, 'ShaderMaterial', 'ShaderMaterial2', 'ExtendedShaderMaterial'],
params: {
vertexShader: shaderUtils.defaultVertex,
fragmentShader: shaderUtils.defaultFragment,
},
generator: (params) => {
return new ObjectShaderMaterial(params)
},
}
}

// todo gltf material extension

+ 9
- 3
src/core/material/PhysicalMaterial.ts Прегледај датотеку

@@ -1,4 +1,4 @@
import {UiObjectConfig} from 'uiconfig.js'
import {generateUiConfig, UiObjectConfig} from 'uiconfig.js'
import {
BufferGeometry,
Camera,
@@ -32,6 +32,11 @@ import {iMaterialUI} from './IMaterialUi'

export type PhysicalMaterialEventTypes = IMaterialEventTypes | ''

/**
* And extension of three.js MeshPhysicalMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization.
*
* @category Materials
*/
export class PhysicalMaterial extends MeshPhysicalMaterial<IMaterialEvent, PhysicalMaterialEventTypes> implements IMaterial<IMaterialEvent, PhysicalMaterialEventTypes> {
declare ['constructor']: typeof PhysicalMaterial
public static readonly TypeSlug = 'pmat'
@@ -135,17 +140,18 @@ export class PhysicalMaterial extends MeshPhysicalMaterial<IMaterialEvent, Physi
},
children: [
...iMaterialUI.base(this),
...generateUiConfig(this),
iMaterialUI.blending(this),
iMaterialUI.polygonOffset(this),
iMaterialUI.aoLightMap(this),
iMaterialUI.roughMetal(this),
iMaterialUI.bumpNormal(this),
iMaterialUI.emission(this),
iMaterialUI.transmission(this),
iMaterialUI.environment(this),
iMaterialUI.aoLightMap(this),
iMaterialUI.clearcoat(this),
iMaterialUI.iridescence(this),
iMaterialUI.sheen(this),
iMaterialUI.polygonOffset(this),
...iMaterialUI.misc(this),
],
}

+ 5
- 0
src/core/material/UnlitLineMaterial.ts Прегледај датотеку

@@ -18,6 +18,11 @@ import {iMaterialUI} from './IMaterialUi'

export type UnlitLineMaterialEventTypes = IMaterialEventTypes | ''

/**
* And extension of three.js LineBasicMaterial that can be assigned to lines, and support threepipe features, uiconfig, and serialization.
*
* @category Materials
*/
export class UnlitLineMaterial extends LineBasicMaterial<IMaterialEvent, UnlitLineMaterialEventTypes> implements IMaterial<IMaterialEvent, UnlitLineMaterialEventTypes> {
declare ['constructor']: typeof UnlitLineMaterial


+ 8
- 2
src/core/material/UnlitMaterial.ts Прегледај датотеку

@@ -8,7 +8,7 @@ import {
Shader,
WebGLRenderer,
} from 'three'
import {UiObjectConfig} from 'uiconfig.js'
import {generateUiConfig, UiObjectConfig} from 'uiconfig.js'
import {
IMaterial,
IMaterialEvent,
@@ -27,6 +27,11 @@ import {iMaterialUI} from './IMaterialUi'

export type UnlitMaterialEventTypes = IMaterialEventTypes | ''

/**
* And extension of three.js MeshBasicMaterial that can be assigned to objects, and support threepipe features, uiconfig, and serialization.
*
* @category Materials
*/
export class UnlitMaterial extends MeshBasicMaterial<IMaterialEvent, UnlitMaterialEventTypes> implements IMaterial<IMaterialEvent, UnlitMaterialEventTypes> {
declare ['constructor']: typeof UnlitMaterial

@@ -177,9 +182,10 @@ export class UnlitMaterial extends MeshBasicMaterial<IMaterialEvent, UnlitMateri
},
children: [
...iMaterialUI.base(this),
...generateUiConfig(this),
iMaterialUI.blending(this),
iMaterialUI.polygonOffset(this),
iMaterialUI.aoLightMap(this),
iMaterialUI.polygonOffset(this),
// iMaterialUI.environment(this),
...iMaterialUI.misc(this),
],

+ 2
- 1
src/utils/shaders.ts Прегледај датотеку

@@ -2,8 +2,9 @@ import simpleCameraHelpers from './shaders/simpleCameraHelpers.glsl'
import cameraHelpers from './shaders/cameraHelpers.glsl'
import randomHelpers from './shaders/randomHelpers.glsl'
import defaultVertex from './shaders/defaultVertex.glsl'
import defaultFragment from './shaders/defaultFragment.glsl'
import voronoiNoise from './shaders/voronoiNoise.glsl'

export const shaderUtils = {
simpleCameraHelpers, cameraHelpers, randomHelpers, defaultVertex, voronoiNoise,
simpleCameraHelpers, cameraHelpers, randomHelpers, defaultVertex, defaultFragment, voronoiNoise,
}

+ 5
- 0
src/utils/shaders/defaultFragment.glsl Прегледај датотеку

@@ -0,0 +1,5 @@

varying vec2 vUv;
void main() {
gl_FragColor = vec4( vUv, 0.0, 1.0 );
}

Loading…
Откажи
Сачувај