Skip to content

Commit

Permalink
Basic shader generation refactoring (#6250)
Browse files Browse the repository at this point in the history
* Basic shader generation refactoring

* feedback

---------

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
  • Loading branch information
mvaligursky and Martin Valigursky authored Apr 12, 2024
1 parent 6277c94 commit af7d32c
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 137 deletions.
12 changes: 8 additions & 4 deletions src/core/preprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,17 @@ class Preprocessor {
* Run c-like preprocessor on the source code, and resolves the code based on the defines and ifdefs
*
* @param {string} source - The source code to work on.
* @param {Map<string, string>} [includes] - An object containing key-value pairs of include names and their
* content.
* @param {Map<string, string>} [defines] - A map containing key-value pairs of define names
* and their values. These are used for resolving #ifdef style of directives in the source.
* @param {Map<string, string>} [includes] - A map containing key-value pairs of include names
* and their content. These are used for resolving #include directives in the source.
* @param {boolean} [stripUnusedColorAttachments] - If true, strips unused color attachments.
* @returns {string|null} Returns preprocessed source code, or null in case of error.
*/
static run(source, includes = new Map(), stripUnusedColorAttachments = false) {
static run(source, defines, includes = new Map(), stripUnusedColorAttachments = false) {

// shallow clone as we will modify the map
defines = defines ? new Map(defines) : new Map();

// strips comments, handles // and many cases of /*
source = source.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1');
Expand All @@ -60,7 +65,6 @@ class Preprocessor {
.join('\n');

// generate defines to remove unused color attachments
const defines = new Map();
if (stripUnusedColorAttachments) {

// find out how many times pcFragColorX is used (see gles3.js)
Expand Down
19 changes: 18 additions & 1 deletion src/platform/graphics/shader-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,20 @@ class ShaderUtils {
* @param {string} [options.fragmentDefines] - The fragment shader defines.
* @param {string} [options.fragmentExtensions] - The fragment shader extensions code.
* @param {string} [options.fragmentPreamble] - The preamble string for the fragment shader.
* @param {boolean} [options.useTransformFeedback] - Whether to use transform feedback. Defaults to false.
* @param {boolean} [options.useTransformFeedback] - Whether to use transform feedback. Defaults
* to false.
* @param {Map<string, string>} [options.vertexIncludesMap] - A map containing key-value pairs of
* include names and their content. These are used for resolving #include directives in the
* vertex shader source.
* @param {Map<string, string>} [options.vertexDefinesMap] - A map containing key-value pairs of
* define names and their values. These are used for resolving #ifdef style of directives in the
* vertex code.
* @param {Map<string, string>} [options.fragmentIncludesMap] - A map containing key-value pairs
* of include names and their content. These are used for resolving #include directives in the
* fragment shader source.
* @param {Map<string, string>} [options.fragmentDefinesMap] - A map containing key-value pairs of
* define names and their values. These are used for resolving #ifdef style of directives in the
* fragment code.
* @param {string | string[]} [options.fragmentOutputTypes] - Fragment shader output types,
* which default to vec4. Passing a string will set the output type for all color attachments.
* Passing an array will set the output type for each color attachment.
Expand Down Expand Up @@ -112,6 +125,10 @@ class ShaderUtils {
name: name,
attributes: attribs,
vshader: vertCode,
vdefines: options.vertexDefinesMap,
vincludes: options.vertexIncludesMap,
fdefines: options.fragmentDefinesMap,
fincludes: options.fragmentIncludesMap,
fshader: fragCode,
useTransformFeedback: options.useTransformFeedback
};
Expand Down
16 changes: 14 additions & 2 deletions src/platform/graphics/shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ class Shader {
* useTransformFeedback or compute shader is specified.
* @param {string} [definition.cshader] - Compute shader source (WGSL code). Only supported on
* WebGPU platform.
* @param {Map<string, string>} [definition.vincludes] - A map containing key-value pairs of
* include names and their content. These are used for resolving #include directives in the
* vertex shader source.
* @param {Map<string, string>} [definition.vdefines] - A map containing key-value pairs of
* define names and their values. These are used for resolving #ifdef style of directives in the
* vertex code.
* @param {Map<string, string>} [definition.fincludes] - A map containing key-value pairs
* of include names and their content. These are used for resolving #include directives in the
* fragment shader source.
* @param {Map<string, string>} [definition.fdefines] - A map containing key-value pairs of
* define names and their values. These are used for resolving #ifdef style of directives in the
* fragment code.
* @param {boolean} [definition.useTransformFeedback] - Specifies that this shader outputs
* post-VS data to a buffer.
* @param {string | string[]} [definition.fragmentOutputTypes] - Fragment shader output types,
Expand Down Expand Up @@ -106,13 +118,13 @@ class Shader {
Debug.assert(definition.fshader, 'No fragment shader has been specified when creating a shader.');

// pre-process shader sources
definition.vshader = Preprocessor.run(definition.vshader);
definition.vshader = Preprocessor.run(definition.vshader, definition.vdefines, definition.vincludes);

// Strip unused color attachments from fragment shader.
// Note: this is only needed for iOS 15 on WebGL2 where there seems to be a bug where color attachments that are not
// written to generate metal linking errors. This is fixed on iOS 16, and iOS 14 does not support WebGL2.
const stripUnusedColorAttachments = graphicsDevice.isWebGL2 && (platform.name === 'osx' || platform.name === 'ios');
definition.fshader = Preprocessor.run(definition.fshader, undefined, stripUnusedColorAttachments);
definition.fshader = Preprocessor.run(definition.fshader, definition.fdefines, definition.fincludes, stripUnusedColorAttachments);
}

this.impl = graphicsDevice.createShaderImpl(this);
Expand Down
4 changes: 4 additions & 0 deletions src/scene/shader-lib/program-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ class ProgramLibrary {
name: `${generatedShaderDef.name}${passName}-proc`,
attributes: generatedShaderDef.attributes,
vshader: generatedShaderDef.vshader,
vdefines: generatedShaderDef.vdefines,
vincludes: generatedShaderDef.vincludes,
fdefines: generatedShaderDef.fdefines,
fincludes: generatedShaderDef.fincludes,
fshader: generatedShaderDef.fshader,
processingOptions: processingOptions,
shaderLanguage: generatedShaderDef.shaderLanguage
Expand Down
Loading

0 comments on commit af7d32c

Please sign in to comment.