@spearwolf/twopoint5d
Version:
a library to create 2.5d realtime graphics and pixelart with three.js
90 lines • 3.54 kB
JavaScript
import { MathUtils, ShaderMaterial, WebGLRenderer, } from 'three';
export class CustomChunksShaderMaterial extends ShaderMaterial {
constructor() {
super(...arguments);
this.#uuid = MathUtils.generateUUID();
this.#chunksSerial = 0;
this.replaceVertexShaderChunks = [];
this.replaceFragmentShaderChunks = [];
this.staticChunks = [];
this.chunks = ((material) => new Proxy({}, {
set(target, propKey, value, receiver) {
if (!(propKey in target) || target[propKey] !== value) {
++material.#chunksSerial;
material.needsUpdate = true;
if (value != null) {
Reflect.set(target, propKey, value, receiver);
}
else {
delete target[propKey];
}
return true;
}
return false;
},
get(target, propKey) {
if (propKey in target) {
return target[propKey];
}
return material.staticChunks.reduce((value, chunks) => (propKey in chunks ? chunks[propKey] : value), undefined);
},
}))(this);
this.logShadersToConsole = false;
}
#uuid;
#chunksSerial;
customProgramCacheKey() {
return `${this.#uuid},${this.#chunksSerial}`;
}
addStaticChunks(chunks) {
if (this.staticChunks.indexOf(chunks) === -1) {
this.staticChunks.push(chunks);
++this.#chunksSerial;
return () => this.removeStaticChunks(chunks);
}
return () => void 0;
}
removeStaticChunks(chunks) {
const idx = this.staticChunks.indexOf(chunks);
if (idx !== -1) {
++this.#chunksSerial;
this.staticChunks.splice(idx, 1);
}
}
#customChunks() {
const chunks = {};
[...this.staticChunks, this.chunks].forEach((staticChunks) => {
Object.entries(staticChunks).forEach(([key, value]) => {
chunks[key] = value;
});
});
return Object.entries(chunks);
}
onBeforeCompile(shader, _renderer) {
const customChunks = this.#customChunks();
const replaceChunk = (shaderType) => (chunkName) => {
shader[shaderType] = customChunks.reduce((source, [customChunkName, customChunkValue]) => source.replace(`#include <${customChunkName}>`, customChunkValue), shader[shaderType].replace(`#include <${chunkName}>`, this.chunks[chunkName] ?? ''));
};
this.replaceVertexShaderChunks.forEach(replaceChunk('vertexShader'));
this.replaceFragmentShaderChunks.forEach(replaceChunk('fragmentShader'));
if (this.logShadersToConsole) {
console.groupCollapsed(`CustomChunksShaderMaterial.onBeforeCompile(), name= ${this.name ?? this.uuid}`);
console.group('vertexShader');
console.log(shader.vertexShader);
console.groupEnd();
console.group('fragmentShader');
console.log(shader.fragmentShader);
console.groupEnd();
console.groupEnd();
}
}
updateBoolDefine(name, value) {
if (value) {
Object.assign(this.defines, this.defines, { [name]: 1 });
}
else if (this.defines) {
delete this.defines[name];
}
}
}
//# sourceMappingURL=CustomChunksShaderMaterial.js.map