Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusted syntax of variables the preprocessor uses for injection #7386

Merged
merged 1 commit into from
Feb 27, 2025
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
41 changes: 25 additions & 16 deletions src/core/preprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const IF = /(ifdef|ifndef|if)[ \t]*([^\r\n]+)\r?\n/g;
// #endif/#else or #elif EXPRESSION
const ENDIF = /(endif|else|elif)(?:[ \t]+([^\r\n]*))?\r?\n?/g;

// identifier
const IDENTIFIER = /([\w-]+)/;
// identifier in form of IDENTIFIER or {IDENTIFIER}
const IDENTIFIER = /\{?[\w-]+\}?/;

// [!]defined(EXPRESSION)
const DEFINED = /(!|\s)?defined\(([\w-]+)\)/;
Expand Down Expand Up @@ -94,8 +94,11 @@ class Preprocessor {
});
}

// extracted defines with name in {} which are to be replaced with their values
const injectDefines = new Map();

// preprocess defines / ifdefs ..
source = this._preprocess(source, defines, includes, options.stripDefines);
source = this._preprocess(source, defines, injectDefines, includes, options.stripDefines);

// extract defines that evaluate to an integer number
const intDefines = new Map();
Expand All @@ -105,14 +108,6 @@ class Preprocessor {
}
});

// extract defines with name starting with _INJECT_
const injectDefines = new Map();
defines.forEach((value, key) => {
if (key.startsWith('_INJECT_')) {
injectDefines.set(key, value);
}
});

// strip comments again after the includes have been resolved
source = this.stripComments(source);

Expand Down Expand Up @@ -190,12 +185,14 @@ class Preprocessor {
* @param {Map<string, string>} defines - Supplied defines which are used in addition to those
* defined in the source code. Maps a define name to its value. Note that the map is modified
* by the function.
* @param {Map<string, string>} injectDefines - An object to collect defines that are to be
* replaced with their values.
* @param {Map<string, string>} [includes] - An object containing key-value pairs of include names and their
* content.
* @param {boolean} [stripDefines] - If true, strips all defines from the source.
* @returns {string} Returns preprocessed source code.
*/
static _preprocess(source, defines = new Map(), includes, stripDefines) {
static _preprocess(source, defines = new Map(), injectDefines, includes, stripDefines) {

const originalSource = source;

Expand All @@ -222,17 +219,29 @@ class Preprocessor {
// split it to identifier name and a value
IDENTIFIER.lastIndex = define.index;
const identifierValue = IDENTIFIER.exec(expression);
const identifier = identifierValue[1];
const identifier = identifierValue[0];
let value = expression.substring(identifier.length).trim();
if (value === '') value = 'true';

// are we inside if-blocks that are accepted
const keep = Preprocessor._keep(stack);
let stripThisDefine = stripDefines;

if (keep) {
defines.set(identifier, value);

if (stripDefines) {
// replacement identifier (inside {}) - always remove it from code
const replacementDefine = identifier.startsWith('{') && identifier.endsWith('}');
if (replacementDefine) {
stripThisDefine = true;
}

if (replacementDefine) {
injectDefines.set(identifier, value);
} else {
defines.set(identifier, value);
}

if (stripThisDefine) {
// cut out the define line
source = source.substring(0, define.index - 1) + source.substring(DEFINE.lastIndex);

Expand All @@ -244,7 +253,7 @@ class Preprocessor {
Debug.trace(TRACEID, `${keyword}: [${identifier}] ${value} ${keep ? '' : 'IGNORED'}`);

// continue on the next line
if (!stripDefines) {
if (!stripThisDefine) {
KEYWORD.lastIndex = define.index + define[0].length;
}
break;
Expand Down
4 changes: 2 additions & 2 deletions src/scene/shader-lib/chunks-wgsl/skybox/frag/skybox.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ export default /* wgsl */`
#endif

dir.x *= -1.0;
linear = _INJECT_SKYBOX_DECODE_FNC(textureSample(texture_cubeMap, texture_cubeMap_sampler, dir));
linear = {SKYBOX_DECODE_FNC}(textureSample(texture_cubeMap, texture_cubeMap_sampler, dir));

#else // env-atlas

dir = input.vViewDir * vec3f(-1.0, 1.0, 1.0);
let uv : vec2f = toSphericalUv(normalize(dir));
linear = _INJECT_SKYBOX_DECODE_FNC(textureSample(texture_envAtlas, texture_envAtlas_sampler, mapRoughnessUv(uv, uniform.mipLevel)));
linear = {SKYBOX_DECODE_FNC}(textureSample(texture_envAtlas, texture_envAtlas_sampler, mapRoughnessUv(uv, uniform.mipLevel)));

#endif

Expand Down
46 changes: 36 additions & 10 deletions src/scene/shader-lib/chunks/lit/frag/clusteredLight.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,51 @@ struct ClusterLightData {
mat4 lightProjectionMatrix;

// macros for light properties
#define isClusteredLightCastShadow(light) ( light.shadowIntensity > 0.0 )
#define isClusteredLightCookie(light) (light.cookie > 0.5 )
#define isClusteredLightCookieRgb(light) (light.cookieRgb > 0.5 )
#define isClusteredLightSpot(light) ( light.lightType > 0.5 )
#define isClusteredLightFalloffLinear(light) ( light.falloffMode < 0.5 )
bool isClusteredLightCastShadow(in ClusterLightData light) {
return light.shadowIntensity > 0.0;
}

bool isClusteredLightCookie(in ClusterLightData light) {
return light.cookie > 0.5;
}

bool isClusteredLightCookieRgb(in ClusterLightData light) {
return light.cookieRgb > 0.5;
}

bool isClusteredLightSpot(in ClusterLightData light) {
return light.lightType > 0.5;
}

bool isClusteredLightFalloffLinear(in ClusterLightData light) {
return light.falloffMode < 0.5;
}

// macros to test light shape
// Note: Following functions need to be called serially in listed order as they do not test both '>' and '<'
#define isClusteredLightArea(light) ( light.shape > 0.1 )
#define isClusteredLightRect(light) ( light.shape < 0.3 )
#define isClusteredLightDisk(light) ( light.shape < 0.6 )
bool isClusteredLightArea(in ClusterLightData light) {
return light.shape > 0.1;
}

bool isClusteredLightRect(in ClusterLightData light) {
return light.shape < 0.3;
}

bool isClusteredLightDisk(in ClusterLightData light) {
return light.shape < 0.6;
}

// macro to test light mask (mesh accepts dynamic vs lightmapped lights)
#ifdef CLUSTER_MESH_DYNAMIC_LIGHTS
// accept lights marked as dynamic or both dynamic and lightmapped
#define acceptLightMask(light) ( light.mask < 0.75)
bool acceptLightMask(in ClusterLightData light) {
return light.mask < 0.75;
}
#else
// accept lights marked as lightmapped or both dynamic and lightmapped
#define acceptLightMask(light) ( light.mask > 0.25)
bool acceptLightMask(in ClusterLightData light) {
return light.mask > 0.25;
}
#endif

vec4 decodeClusterLowRange4Vec4(vec4 d0, vec4 d1, vec4 d2, vec4 d3) {
Expand Down
6 changes: 3 additions & 3 deletions src/scene/shader-lib/chunks/lit/vert/uvTransform.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// chunk that generates uv coordinate transformed by uv transform matrix
export default /* glsl */`
vUV_INJECT_TRANSFORM_UV_{i}__INJECT_TRANSFORM_ID_{i} = vec2(
dot(vec3(uv_INJECT_TRANSFORM_UV_{i}, 1), _INJECT_TRANSFORM_NAME_{i}0),
dot(vec3(uv_INJECT_TRANSFORM_UV_{i}, 1), _INJECT_TRANSFORM_NAME_{i}1)
vUV{TRANSFORM_UV_{i}}_{TRANSFORM_ID_{i}} = vec2(
dot(vec3(uv{TRANSFORM_UV_{i}}, 1), {TRANSFORM_NAME_{i}}0),
dot(vec3(uv{TRANSFORM_UV_{i}}, 1), {TRANSFORM_NAME_{i}}1)
);
`;
4 changes: 2 additions & 2 deletions src/scene/shader-lib/chunks/lit/vert/uvTransformUniforms.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// uniform declaration for uv transform matrix, 3x2 matrix
export default /* glsl */`
uniform vec3 _INJECT_TRANSFORM_NAME_{i}0;
uniform vec3 _INJECT_TRANSFORM_NAME_{i}1;
uniform vec3 {TRANSFORM_NAME_{i}}0;
uniform vec3 {TRANSFORM_NAME_{i}}1;
`;
4 changes: 2 additions & 2 deletions src/scene/shader-lib/chunks/skybox/frag/skybox.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ export default /* glsl */`
#endif

dir.x *= -1.0;
vec3 linear = _INJECT_SKYBOX_DECODE_FNC(textureCube(texture_cubeMap, dir));
vec3 linear = {SKYBOX_DECODE_FNC}(textureCube(texture_cubeMap, dir));

#else // env-atlas

vec3 dir = vViewDir * vec3(-1.0, 1.0, 1.0);
vec2 uv = toSphericalUv(normalize(dir));

vec3 linear = _INJECT_SKYBOX_DECODE_FNC(texture2D(texture_envAtlas, mapRoughnessUv(uv, mipLevel)));
vec3 linear = {SKYBOX_DECODE_FNC}(texture2D(texture_envAtlas, mapRoughnessUv(uv, mipLevel)));

#endif

Expand Down
6 changes: 3 additions & 3 deletions src/scene/shader-lib/programs/lit-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ class LitShader {

// defines used by the included chunks
const varName = `texture_${name}MapTransform`;
vDefines.set(`_INJECT_TRANSFORM_NAME_${numTransforms}`, varName);
vDefines.set(`_INJECT_TRANSFORM_UV_${numTransforms}`, uv);
vDefines.set(`_INJECT_TRANSFORM_ID_${numTransforms}`, id);
vDefines.set(`{TRANSFORM_NAME_${numTransforms}}`, varName);
vDefines.set(`{TRANSFORM_UV_${numTransforms}}`, uv);
vDefines.set(`{TRANSFORM_ID_${numTransforms}}`, id);

numTransforms++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/scene/skybox/sky-mesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class SkyMesh {
});

// defines
material.setDefine('_INJECT_SKYBOX_DECODE_FNC', ChunkUtils.decodeFunc(texture.encoding));
material.setDefine('{SKYBOX_DECODE_FNC}', ChunkUtils.decodeFunc(texture.encoding));
if (type !== SKYTYPE_INFINITE) material.setDefine('SKYMESH', '');
if (texture.cubemap) material.setDefine('SKY_CUBEMAP', '');

Expand Down
8 changes: 4 additions & 4 deletions test/core/preprocessor.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ describe('Preprocessor', function () {
const srcData = `

#define LOOP_COUNT 3
#define _INJECT_COUNT 2
#define _INJECT_STRING hello
#define {COUNT} 2
#define {STRING} hello
#define FEATURE1
#define FEATURE2
#define AND1
Expand Down Expand Up @@ -126,8 +126,8 @@ describe('Preprocessor', function () {
CMP5
#endif

TESTINJECTION _INJECT_COUNT
INJECTSTRING _INJECT_STRING(x)
TESTINJECTION {COUNT}
INJECTSTRING {STRING}(x)
`;

it('returns false for MORPH_A', function () {
Expand Down