Skip to content

Commit

Permalink
GsplatMaterial interally uses ShaderMaterial to generate variants (#7302
Browse files Browse the repository at this point in the history
)

Co-authored-by: Martin Valigursky <[email protected]>
  • Loading branch information
mvaligursky and Martin Valigursky authored Jan 20, 2025
1 parent e101b08 commit 7a26a64
Showing 1 changed file with 12 additions and 70 deletions.
82 changes: 12 additions & 70 deletions src/scene/gsplat/gsplat-material.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,7 @@
import { CULLFACE_NONE, SEMANTIC_ATTR13, SEMANTIC_POSITION } from '../../platform/graphics/constants.js';
import { ShaderProcessorOptions } from '../../platform/graphics/shader-processor-options.js';
import { BLEND_NONE, BLEND_NORMAL, DITHER_NONE } from '../constants.js';
import { ShaderMaterial } from '../materials/shader-material.js';
import { getProgramLibrary } from '../shader-lib/get-program-library.js';
import { getCoreDefines } from '../shader-lib/utils.js';
import { ShaderUtils } from '../../platform/graphics/shader-utils.js';
import { shaderChunks } from '../shader-lib/chunks/chunks.js';
import { ShaderGenerator } from '../shader-lib/programs/shader-generator.js';
import { hashCode } from '../../core/hash.js';

const defaultChunks = new Map(Object.entries(shaderChunks));

class GSplatShaderGenerator {
generateKey(options) {
const { vertex, fragment, dither, defines, chunks } = options;
return `splat-${hashCode(vertex)}-${hashCode(fragment)}-${dither}-${ShaderGenerator.definesHash(defines)}-${chunks && Object.keys(chunks).sort().join(':')}`;
}

createShaderDefinition(device, options) {

const defineMap = new Map(options.defines);

// it would nice if DITHER type was defined like the others
defineMap.set(`DITHER_${options.dither.toUpperCase()}`, true);

const vs = options.vertex ?? shaderChunks.gsplatVS;
const fs = options.fragment ?? shaderChunks.gsplatPS;
const includes = options.chunks ? new Map(Object.entries({
...shaderChunks,
...options.chunks
})) : defaultChunks;

return ShaderUtils.createDefinition(device, {
name: 'SplatShader',
attributes: {
vertex_position: SEMANTIC_POSITION,
vertex_id_attrib: SEMANTIC_ATTR13
},
vertexCode: vs,
vertexDefines: defineMap,
vertexIncludes: includes,
fragmentCode: fs,
fragmentDefines: defineMap,
fragmentIncludes: includes
});
}
}

const gsplat = new GSplatShaderGenerator();

/**
* @typedef {object} SplatMaterialOptions - The options.
Expand All @@ -69,33 +23,21 @@ const createGSplatMaterial = (options = {}) => {
const ditherEnum = options.dither ?? DITHER_NONE;
const dither = ditherEnum !== DITHER_NONE;

const material = new ShaderMaterial();
material.name = 'splatMaterial';
const material = new ShaderMaterial({
uniqueName: 'SplatMaterial',
vertexCode: options.vertex ?? shaderChunks.gsplatVS,
fragmentCode: options.fragment ?? shaderChunks.gsplatPS,
attributes: {
vertex_position: SEMANTIC_POSITION,
vertex_id_attrib: SEMANTIC_ATTR13
}
});

material.setDefine(`DITHER_${ditherEnum.toUpperCase()}`, '');

material.cull = CULLFACE_NONE;
material.blendType = dither ? BLEND_NONE : BLEND_NORMAL;
material.depthWrite = dither;

material.getShaderVariant = function (params) {

const { cameraShaderParams } = params;
const programOptions = {
defines: getCoreDefines(material, params),
pass: params.pass,
gamma: cameraShaderParams.shaderOutputGamma,
toneMapping: cameraShaderParams.toneMapping,
vertex: options.vertex,
fragment: options.fragment,
chunks: options.chunks,
dither: ditherEnum
};

const processingOptions = new ShaderProcessorOptions(params.viewUniformFormat, params.viewBindGroupFormat);

const library = getProgramLibrary(params.device);
library.register('splat', gsplat);
return library.getProgram('splat', programOptions, processingOptions);
};

material.update();

return material;
Expand Down

0 comments on commit 7a26a64

Please sign in to comment.