diff --git a/src/foundation/materials/core/Material.ts b/src/foundation/materials/core/Material.ts index bcc1cc9f4..35d5646cf 100644 --- a/src/foundation/materials/core/Material.ts +++ b/src/foundation/materials/core/Material.ts @@ -59,7 +59,6 @@ export class Material extends RnObject { // Ids private _shaderProgramUidMap: Map = new Map(); - private _primitiveFingerPrintBackUp: PrimitiveFingerPrint = ''; __materialUid: MaterialUID = -1; private __materialTid: MaterialTID; __materialSid: MaterialSID = -1; // material serial Id in the material type @@ -280,7 +279,7 @@ export class Material extends RnObject { * called from WebGLStrategyDataTexture and WebGLStrategyUniform only * @param isUniformOnlyMode */ - _setUniformLocationsOfMaterialNodes(isUniformOnlyMode: boolean, primitive?: Primitive) { + _setUniformLocationsOfMaterialNodes(isUniformOnlyMode: boolean, primitive: Primitive) { const webglResourceRepository = CGAPIResourceRepository.getWebGLResourceRepository(); let array: ShaderSemanticsInfo[] = []; @@ -289,15 +288,12 @@ export class Material extends RnObject { array = array.concat(semanticsInfoArray); } - const shaderProgramUid = this._shaderProgramUidMap.get( - primitive != null ? primitive._getFingerPrint() : this._primitiveFingerPrintBackUp - ); + const shaderProgramUid = this._shaderProgramUidMap.get(primitive._getFingerPrint()); webglResourceRepository.setupUniformLocations(shaderProgramUid!, array, isUniformOnlyMode); } - getShaderProgramUid(primitive?: Primitive): CGAPIResourceHandle { - const primitiveFingerPrint = - primitive !== undefined ? primitive._getFingerPrint() : this._primitiveFingerPrintBackUp; + getShaderProgramUid(primitive: Primitive): CGAPIResourceHandle { + const primitiveFingerPrint = primitive._getFingerPrint(); return this._shaderProgramUidMap.get(primitiveFingerPrint) ?? -1; } @@ -338,7 +334,6 @@ export class Material extends RnObject { isWebGL2 ); this._shaderProgramUidMap.set(primitive._getFingerPrint(), programUid); - this._primitiveFingerPrintBackUp = primitive._getFingerPrint(); Material.__stateVersion++; @@ -360,7 +355,6 @@ export class Material extends RnObject { ); this._shaderProgramUidMap.set(primitive._getFingerPrint(), programUid); - this._primitiveFingerPrintBackUp = primitive._getFingerPrint(); Material.__stateVersion++; } @@ -375,15 +369,17 @@ export class Material extends RnObject { */ _createProgramByUpdatedSources( updatedShaderSources: ShaderSources, + primitive: Primitive, onError?: (message: string) => void ): [CGAPIResourceHandle, boolean] { const [programUid, newOne] = _createProgramAsSingleOperationByUpdatedSources( this, + primitive, this._materialContent, updatedShaderSources, onError ); - this._shaderProgramUidMap.set(this._primitiveFingerPrintBackUp, programUid); + this._shaderProgramUidMap.set(primitive._getFingerPrint(), programUid); if (programUid > 0) { // this.__updatedShaderSources = updatedShaderSources; @@ -397,11 +393,10 @@ export class Material extends RnObject { * @internal * called WebGLStrategyDataTexture and WebGLStrategyUniform only */ - _setupBasicUniformsLocations(primitive?: Primitive) { + _setupBasicUniformsLocations(primitive: Primitive) { const webglResourceRepository = CGAPIResourceRepository.getWebGLResourceRepository(); - const primitiveFingerPrint = - primitive != null ? primitive._getFingerPrint() : this._primitiveFingerPrintBackUp; + const primitiveFingerPrint = primitive._getFingerPrint(); const shaderProgramUid = this._shaderProgramUidMap.get(primitiveFingerPrint); webglResourceRepository.setupBasicUniformLocations(shaderProgramUid!); } @@ -413,11 +408,10 @@ export class Material extends RnObject { _setupAdditionalUniformLocations( shaderSemantics: ShaderSemanticsInfo[], isUniformOnlyMode: boolean, - primitive?: Primitive + primitive: Primitive ) { const webglResourceRepository = CGAPIResourceRepository.getWebGLResourceRepository(); - const primitiveFingerPrint = - primitive != null ? primitive._getFingerPrint() : this._primitiveFingerPrintBackUp; + const primitiveFingerPrint = primitive._getFingerPrint(); const shaderProgramUid = this._shaderProgramUidMap.get(primitiveFingerPrint); webglResourceRepository.setupUniformLocations( shaderProgramUid!, diff --git a/src/foundation/materials/core/ShaderHandler.ts b/src/foundation/materials/core/ShaderHandler.ts index 333c35215..3d26265b3 100644 --- a/src/foundation/materials/core/ShaderHandler.ts +++ b/src/foundation/materials/core/ShaderHandler.ts @@ -24,6 +24,7 @@ export class ShaderHandler { /** * Create a shader program Or Get a shader program from cache * @param material + * @param primitive * @param vertexShader * @param pixelShader * @param attributeNames @@ -33,6 +34,7 @@ export class ShaderHandler { */ static _createShaderProgramWithCache( material: Material, + primitive: Primitive, vertexShader: string, pixelShader: string, attributeNames: AttributeNames, @@ -49,6 +51,7 @@ export class ShaderHandler { const cgApiResourceRepository = CGAPIResourceRepository.getCgApiResourceRepository(); shaderProgramUid = cgApiResourceRepository.createShaderProgram({ material, + primitive, vertexShaderStr: vertexShader, fragmentShaderStr: pixelShader, attributeNames: attributeNames, @@ -62,6 +65,7 @@ export class ShaderHandler { export function _createProgramAsSingleOperationByUpdatedSources( material: Material, + primitive: Primitive, materialNode: AbstractMaterialContent, updatedShaderSources: ShaderSources, onError?: (message: string) => void @@ -70,6 +74,7 @@ export function _createProgramAsSingleOperationByUpdatedSources( const [shaderProgramUid, newOne] = ShaderHandler._createShaderProgramWithCache( material, + primitive, updatedShaderSources.vertex, updatedShaderSources.pixel, attributeNames, @@ -182,6 +187,7 @@ export function _createProgramAsSingleOperationWebGL( const [shaderProgramUid, newOne] = ShaderHandler._createShaderProgramWithCache( material, + primitive, vertexShader, pixelShader, attributeNames, @@ -307,6 +313,7 @@ export function _createProgramAsSingleOperationWebGpu( const [programUid, newOne] = ShaderHandler._createShaderProgramWithCache( material, + primitive, preprocessedVertex.code, preprocessedPixel.code, [], diff --git a/src/foundation/renderer/CGAPIResourceRepository.ts b/src/foundation/renderer/CGAPIResourceRepository.ts index 22779a623..371a54ac7 100644 --- a/src/foundation/renderer/CGAPIResourceRepository.ts +++ b/src/foundation/renderer/CGAPIResourceRepository.ts @@ -226,6 +226,7 @@ export interface ICGAPIResourceRepository { */ createShaderProgram({ material, + primitive, vertexShaderStr, fragmentShaderStr, attributeNames, @@ -233,6 +234,7 @@ export interface ICGAPIResourceRepository { onError, }: { material: Material; + primitive: Primitive; vertexShaderStr: string; fragmentShaderStr: string; attributeNames: AttributeNames; diff --git a/src/webgl/WebGLExtendedTypes.ts b/src/webgl/WebGLExtendedTypes.ts index 2cc8d2024..8a3ea45c0 100644 --- a/src/webgl/WebGLExtendedTypes.ts +++ b/src/webgl/WebGLExtendedTypes.ts @@ -1,5 +1,6 @@ import { ShaderSemanticsName } from '../foundation/definitions/ShaderSemantics'; import { ShaderSemanticsInfo } from '../foundation/definitions/ShaderSemanticsInfo'; +import { Primitive } from '../foundation/geometry/Primitive'; import { Material } from '../foundation/materials/core/Material'; export interface RnWebGLProgram extends WebGLProgram { @@ -10,6 +11,7 @@ export interface RnWebGLProgram extends WebGLProgram { _shaderSemanticsInfoMap: Map; __SPECTOR_rebuildProgram: unknown; _material: WeakRef; + _primitive: WeakRef; } export interface RnWebGLTexture extends WebGLTexture { diff --git a/src/webgl/WebGLResourceRepository.ts b/src/webgl/WebGLResourceRepository.ts index 9c1b5dff2..a312efb21 100644 --- a/src/webgl/WebGLResourceRepository.ts +++ b/src/webgl/WebGLResourceRepository.ts @@ -361,6 +361,7 @@ export class WebGLResourceRepository */ createShaderProgram({ material, + primitive, vertexShaderStr, fragmentShaderStr, attributeNames, @@ -368,6 +369,7 @@ export class WebGLResourceRepository onError, }: { material: Material; + primitive: Primitive; vertexShaderStr: string; fragmentShaderStr: string; attributeNames: AttributeNames; @@ -416,6 +418,7 @@ export class WebGLResourceRepository shaderProgram._fragmentShaderStr = fragmentShaderStr; shaderProgram._shaderSemanticsInfoMap = new Map(); shaderProgram._material = new WeakRef(material); + shaderProgram._primitive = new WeakRef(primitive); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); @@ -2882,6 +2885,7 @@ vec4 fetchVec4FromVec4Block(int vec4Idx) { const programUid = renderingStrategy._reSetupShaderForMaterialBySpector( material, + this._primitive.deref()!, { vertex: modifiedVertexSourceCode, pixel: modifiedPixelSourceCode, diff --git a/src/webgl/WebGLStrategy.ts b/src/webgl/WebGLStrategy.ts index e783ddc16..4193cfe11 100644 --- a/src/webgl/WebGLStrategy.ts +++ b/src/webgl/WebGLStrategy.ts @@ -19,6 +19,7 @@ export interface WebGLStrategy { setupShaderForMaterial(material: Material, primitive: Primitive): CGAPIResourceHandle; _reSetupShaderForMaterialBySpector( material: Material, + primitive: Primitive, updatedShaderSources: ShaderSources, onError: (message: string) => void ): CGAPIResourceHandle; diff --git a/src/webgl/WebGLStrategyDataTexture.ts b/src/webgl/WebGLStrategyDataTexture.ts index 8a552db9f..b8c4c299b 100644 --- a/src/webgl/WebGLStrategyDataTexture.ts +++ b/src/webgl/WebGLStrategyDataTexture.ts @@ -190,11 +190,13 @@ export class WebGLStrategyDataTexture implements CGAPIStrategy, WebGLStrategy { */ public _reSetupShaderForMaterialBySpector( material: Material, + primitive: Primitive, updatedShaderSources: ShaderSources, onError: (message: string) => void ): CGAPIResourceHandle { const [programUid, newOne] = material._createProgramByUpdatedSources( updatedShaderSources, + primitive, onError ); if (programUid === CGAPIResourceRepository.InvalidCGAPIResourceUid) { @@ -202,18 +204,19 @@ export class WebGLStrategyDataTexture implements CGAPIStrategy, WebGLStrategy { } if (newOne) { - material._setupBasicUniformsLocations(); + material._setupBasicUniformsLocations(primitive); - material._setUniformLocationsOfMaterialNodes(false); + material._setUniformLocationsOfMaterialNodes(false, primitive); material._setupAdditionalUniformLocations( WebGLStrategyCommonMethod.getPointSpriteShaderSemanticsInfoArray(), - false + false, + primitive ); } WebGLStrategyDataTexture.__globalDataRepository._setUniformLocationsForDataTextureModeOnly( - material.getShaderProgramUid() + material.getShaderProgramUid(primitive) ); return programUid; diff --git a/src/webgl/WebGLStrategyUniform.ts b/src/webgl/WebGLStrategyUniform.ts index 835ebc7a7..5990eea7c 100644 --- a/src/webgl/WebGLStrategyUniform.ts +++ b/src/webgl/WebGLStrategyUniform.ts @@ -211,11 +211,13 @@ bool get_isBillboard(float instanceId) { */ public _reSetupShaderForMaterialBySpector( material: Material, + primitive: Primitive, updatedShaderSources: ShaderSources, onError: (message: string) => void ): CGAPIResourceHandle { const [programUid, newOne] = material._createProgramByUpdatedSources( updatedShaderSources, + primitive, onError ); if (programUid === CGAPIResourceRepository.InvalidCGAPIResourceUid) { @@ -223,9 +225,9 @@ bool get_isBillboard(float instanceId) { } if (newOne) { - material._setupBasicUniformsLocations(); + material._setupBasicUniformsLocations(primitive); - material._setUniformLocationsOfMaterialNodes(true); + material._setUniformLocationsOfMaterialNodes(true, primitive); const shaderSemanticsInfos = WebGLStrategyUniform.componentMatrices; const shaderSemanticsInfosPointSprite = @@ -233,12 +235,13 @@ bool get_isBillboard(float instanceId) { material._setupAdditionalUniformLocations( shaderSemanticsInfos.concat(shaderSemanticsInfosPointSprite), - true + true, + primitive ); } WebGLStrategyUniform.__globalDataRepository._setUniformLocationsForUniformModeOnly( - material.getShaderProgramUid() + material.getShaderProgramUid(primitive) ); return programUid; diff --git a/src/webgpu/WebGpuResourceRepository.ts b/src/webgpu/WebGpuResourceRepository.ts index 358657cfb..dfe87da77 100644 --- a/src/webgpu/WebGpuResourceRepository.ts +++ b/src/webgpu/WebGpuResourceRepository.ts @@ -773,6 +773,7 @@ export class WebGpuResourceRepository */ createShaderProgram({ material, + primitive, vertexShaderStr, fragmentShaderStr, attributeNames, @@ -780,6 +781,7 @@ export class WebGpuResourceRepository onError, }: { material: Material; + primitive: Primitive; vertexShaderStr: string; fragmentShaderStr: string; attributeNames: AttributeNames;