Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/core/map-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Map utility functions.
*
* @ignore
*/
class MapUtils {
/**
* Merges multiple maps into a new Map instance. If multiple maps contain the same key, the
* value from the later map in the arguments list takes precedence.
*
* Null or undefined maps are safely handled and skipped during the merge process.
*
* @param {...(Map|null|undefined)} maps - Maps to merge.
* @returns {Map} A new Map containing all entries from the input maps with conflicts resolved.
* @example
* // Create a merged map where entries from map2 override entries from map1
* const mergedMap = MapUtils.merge(map1, map2);
*/
static merge(...maps) {
// Start with a copy of the first map for better performance with large maps
const result = new Map(maps[0] ?? []);

// Add entries from remaining maps, overriding existing keys
for (let i = 1; i < maps.length; i++) {
const map = maps[i];
if (map) {
for (const [key, value] of map) {
result.set(key, value);
}
}
}
return result;
}
}

export { MapUtils };
2 changes: 1 addition & 1 deletion src/scene/gsplat/gsplat-material.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ShaderMaterial } from '../materials/shader-material.js';
import { ShaderChunks } from '../shader-lib/shader-chunks.js';

/**
* import { GraphicsDevice } from '../../platform/graphics/graphics-device.js'
* @import { GraphicsDevice } from '../../platform/graphics/graphics-device.js'
*/

/**
Expand Down
7 changes: 3 additions & 4 deletions src/scene/shader-lib/programs/lit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ShaderGenerator } from './shader-generator.js';
import { SHADERLANGUAGE_WGSL, SHADERTAG_MATERIAL } from '../../../platform/graphics/constants.js';
import { ShaderDefinitionUtils } from '../../../platform/graphics/shader-definition-utils.js';
import { hashCode } from '../../../core/hash.js';
import { MapUtils } from '../../../core/map-utils.js';

/**
* @import { GraphicsDevice } from '../../../platform/graphics/graphics-device.js'
Expand Down Expand Up @@ -46,10 +47,8 @@ class ShaderGeneratorLit extends ShaderGenerator {

litShader.generateFragmentShader('', litShader.shaderLanguage === SHADERLANGUAGE_WGSL ? options.shaderChunkWGSL : options.shaderChunkGLSL, 'vUv0');

const includes = new Map(Object.entries({
...Object.fromEntries(litShader.chunks), // chunks collected by the lit shader
...Object.fromEntries(litShader.includes) // includes generated by the lit shader
}));
// chunks collected by the lit shader + includes generated by the lit shader
const includes = MapUtils.merge(litShader.chunks, litShader.includes);

const vDefines = litShader.vDefines;
options.defines.forEach((value, key) => vDefines.set(key, value));
Expand Down
7 changes: 3 additions & 4 deletions src/scene/shader-lib/programs/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { LitOptionsUtils } from './lit-options-utils.js';
import { ShaderGenerator } from './shader-generator.js';
import { ShaderDefinitionUtils } from '../../../platform/graphics/shader-definition-utils.js';
import { SHADERTAG_MATERIAL } from '../../../platform/graphics/constants.js';
import { MapUtils } from '../../../core/map-utils.js';

/**
* @import { GraphicsDevice } from '../../../platform/graphics/graphics-device.js'
Expand Down Expand Up @@ -437,10 +438,8 @@ class ShaderGeneratorStandard extends ShaderGenerator {
// use the outputs from this standard shader generator as an input to the lit shader generator
litShader.generateFragmentShader(litShader.chunks.get('stdDeclarationPS'), litShader.chunks.get('stdFrontEndPS'), lightingUv);

const includes = new Map(Object.entries({
...Object.fromEntries(litShader.chunks), // chunks collected by the lit shader
...Object.fromEntries(litShader.includes) // includes generated by the lit shader
}));
// chunks collected by the lit shader + includes generated by the lit shader
const includes = MapUtils.merge(litShader.chunks, litShader.includes);

const vDefines = litShader.vDefines;
options.defines.forEach((value, key) => vDefines.set(key, value));
Expand Down
5 changes: 3 additions & 2 deletions src/scene/shader-lib/shader-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ShaderGenerator } from './programs/shader-generator.js';
import { ShaderPass } from '../shader-pass.js';
import { SHADERLANGUAGE_GLSL, SHADERLANGUAGE_WGSL } from '../../platform/graphics/constants.js';
import { ShaderChunks } from './shader-chunks.js';
import { MapUtils } from '../../core/map-utils.js';

/**
* @import { GraphicsDevice } from '../../platform/graphics/graphics-device.js'
Expand Down Expand Up @@ -99,8 +100,8 @@ class ShaderUtils {
Debug.assert(fragmentCode, 'ShaderUtils.createShader: fragment shader code not provided', options);

// add default shader chunks to includes
const fragmentIncludes = options.fragmentIncludes ? new Map([...chunksMap, ...options.fragmentIncludes]) : new Map(chunksMap);
const vertexIncludes = options.vertexIncludes ? new Map([...chunksMap, ...options.vertexIncludes]) : new Map(chunksMap);
const fragmentIncludes = MapUtils.merge(chunksMap, options.fragmentIncludes);
const vertexIncludes = MapUtils.merge(chunksMap, options.vertexIncludes);

shader = new Shader(device, ShaderDefinitionUtils.createDefinition(device, {
name: options.uniqueName,
Expand Down