owned this note
owned this note
Published
Linked with GitHub
# [\#50 Issue](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50) `open`: Address common community WGSL string interpolation cases in WESL
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) opened issue at [2024-10-03 17:49](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50):
Community projects in WGSL (and other shader communities) typically rely on string interpolation to inject some host specific variation into shaders.
Let's enumerate the common string interpolation use cases in this issue (and make separate issues for the uncommon cases) and then document them on the spec site.
We originally planned to address these common cases by standardizing a string interpolation mechanism (see [SimpleTemplating](https://github.com/wgsl-tooling-wg/wesl-spec/blob/main/SimpleTemplating.md)). I think the current discussions lean towards more precise language features than string insertion, but either way a clear understanding of the use cases will help validate our solutions. When we agree on spec features to address these community use cases, we can document them alongside.
#### <img src="https://avatars.githubusercontent.com/u/16296136?u=a181937f1d7eec6098bd893100ff0a6bfb217198&v=4" width="50">[k2d222](https://github.com/k2d222) commented at [2024-10-03 19:50](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2392208892):
Some of what I have seen (mostly glsl)
* substitute a function name (similar to @link)
* concatenate identifiers, e.g. `alias array${N}f = array<f32, ${N}>;`
* inject a bunch of code, for example a prelude, polyfills, or imports.
* repeat N times, unroll loops or implement recursion (usually implemented with other special markers in code)
* feature flags, e.g. `const my_feat: bool = ${MY_FEAT_ENABLED};`
* inject cpu-precomputed math: e.g. `let my_const = ${3+2}`
* conditional compilation (with string injections that may be empty) e.g. `${DEBUG_BEGIN} ... some stuff ... ${DEBUG_END}`
* writing metadata in the file: build date, time, file name, line number, deploy url, file hash...
* markers for parsing
* stateful injections, e.g. `@bind(${i++})`
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-04 04:33](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2392801224):
pixijs: host code controlled linking via string insertion [here](https://github.com/pixijs/pixijs/blob/be34c9b3b1e67451ca3bd39d4e75e3a2774d3b9f/src/filters/blend-modes/blend-template.wgsl#L58)
pixijs: aligning vert and frag `@location` indices [here](https://github.com/pixijs/pixijs/blob/be34c9b3b1e67451ca3bd39d4e75e3a2774d3b9f/src/filters/defaults/blur/gpu/blur-template.wgsl#L72)
pixijs: custom code generation for blur filter: [here](https://github.com/pixijs/pixijs/blob/be34c9b3b1e67451ca3bd39d4e75e3a2774d3b9f/src/filters/defaults/blur/gpu/generateBlurProgram.ts#L20)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 01:12](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394844460):
[nanite-webgpu](https://github.com/Scthe/nanite-webgpu.git)
* all wgsl is inline TypeScript strings
* string insertion for numeric constants for [array sizes](https://github.com/Scthe/nanite-webgpu/blob/629232f198f91643f06cc9c4815dca96cd7bea83/src/passes/_shaderSnippets/shading.wgsl.ts#L45), [const values](https://github.com/Scthe/nanite-webgpu/blob/629232f198f91643f06cc9c4815dca96cd7bea83/src/passes/_shaderSnippets/shading.wgsl.ts#L10)
* static module linking (via string insertion) [example](https://github.com/Scthe/nanite-webgpu/blob/629232f198f91643f06cc9c4815dca96cd7bea83/src/passes/cullInstances/cullInstancesPass.wgsl.ts#L4)
* [binding numbers inserted by host code](https://github.com/Scthe/nanite-webgpu/blob/629232f198f91643f06cc9c4815dca96cd7bea83/src/passes/rasterizeSw/rasterizeSwPass.wgsl.ts#L28)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 03:59](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394912213):
[lygia](https://github.com/patriciogonzalezvivo/lygia/blob/main/math/aafract.wgsl)
* mostly static functions
* assumes existence of an `#include` facility
* glsl versions use `#define` and possibly function overloading, wished for features in WGSL
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 04:02](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394913136):
[webgpu-torch](https://github.com/praeclarum/webgpu-torch/blob/main/README.md)
* full custom [code generation](https://github.com/praeclarum/webgpu-torch/blob/920ceead3653ba34ed0ef60f234dfbe092e60599/src/kernel.ts#L323)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 04:19](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394918308):
[pbmpm](https://github.com/electronicarts/pbmpm)
* home grown [include / insert](https://github.com/electronicarts/pbmpm/blob/e0536f8fad0278a6d9e4a0057fd9ca7d4593a360/src/shader.js#L77)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 04:29](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394920523):
[frostbitten-hair-webgpu](https://github.com/Scthe/frostbitten-hair-webgpu)
* wgsl in TypeScript strings
* [static module insertion](https://github.com/Scthe/frostbitten-hair-webgpu/blob/4478dd129525ff7db92978178b55f760716cbd72/src/passes/aoPass/aoPass.wgsl.ts#L1)
* [uniforms](${RenderUniformsBuffer.SHADER_SNIPPET(b.renderUniforms)})
(ah, same author as nanite-webgpu, similar techniques)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-05 04:42](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2394923654):
[gpu-curtains](https://github.com/martinlaxenaire/gpu-curtains)
- wgsl as js strings
- [import by string insertion](https://github.com/martinlaxenaire/gpu-curtains/blob/9f601ac22c8832f7610e673abb5a9a1b15a0a3f1/src/core/shaders/chunks/helpers/lights/light_utils.wgsl.js#L4)
- [numeric constants from host](https://github.com/martinlaxenaire/gpu-curtains/blob/9f601ac22c8832f7610e673abb5a9a1b15a0a3f1/src/core/shaders/chunks/helpers/constants.wgsl.js#L3)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 02:26](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395264415):
[alpenglow](https://github.com/phetsims/alpenglow)
- the most advanced templating system I've seen for WGSL: [example](https://github.com/phetsims/alpenglow/blob/main/js/webgpu/wgsl/gpu/mainReduceWGSL.ts)
- modular string templates [take arguments](https://github.com/phetsims/alpenglow/blob/33003e2d5d61ba6e0c885eb5be29688c519f1c6f/js/webgpu/wgsl/gpu/mergeWGSL.ts#L112C13-L112C26)
- code generating string templates can do [loop unrolling](https://github.com/phetsims/alpenglow/blob/33003e2d5d61ba6e0c885eb5be29688c519f1c6f/js/webgpu/wgsl/gpu/scanWGSL.ts#L102), [conditions](https://github.com/phetsims/alpenglow/blob/33003e2d5d61ba6e0c885eb5be29688c519f1c6f/js/webgpu/wgsl/gpu/mainRadixScatterWGSL.ts#L173), [imports](https://github.com/phetsims/alpenglow/blob/33003e2d5d61ba6e0c885eb5be29688c519f1c6f/js/webgpu/wgsl/gpu/mainRadixScatterWGSL.ts#L7), etc.
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 02:36](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395266441):
[Egrogia](https://github.com/Uriopass/Egregoria)
- custom `#include` and `#ifdef` [preprocessor](https://github.com/Uriopass/Egregoria/blob/4ce3db1d38c06953af78c1eee0bf6286ad894bf3/engine/src/shader.rs#L127)
- (no runtime injection of strings or numbers AFAICT)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 02:41](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395267767):
[strahl](https://github.com/StuckiSimon/strahl/tree/main)
- wgsl in typescript strings
- [import by string insertion](https://github.com/StuckiSimon/strahl/blob/65d751332c2ba3c0a70480d4b64d34251a7d5931/strahl-lib/src/shaders/denoise-pass-shader.ts#L1)
- no runtime injection via strings, some use of [`override`](https://github.com/StuckiSimon/strahl/blob/65d751332c2ba3c0a70480d4b64d34251a7d5931/strahl-lib/src/shaders/denoise-pass-shader.ts#L12)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 04:59](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395294786):
[luma.gl](https://github.com/visgl/luma.gl)
- wgsl in typescript strings
- string substitution for [uniforms](https://github.com/visgl/luma.gl/blob/bd27f0b51114c751900525b366991e35a542e950/modules/engine/src/modules/picking/index-picking.ts#L13)
- [wgsl fragment insertion](https://github.com/visgl/luma.gl/blob/bd27f0b51114c751900525b366991e35a542e950/modules/engine/src/models/clip-space.ts#L11)
- uses [reflection](https://github.com/visgl/luma.gl/blob/master/modules/shadertools/src/lib/wgsl/get-shader-layout-wgsl.ts) on constructed WGSL shader to integrate with TypeScript host code
- [fn name selection](https://github.com/visgl/luma.gl/blob/bd27f0b51114c751900525b366991e35a542e950/modules/engine/src/passes/get-fragment-shader.ts#L54)
- [bound variable insertion?](https://github.com/visgl/luma.gl/blob/bd27f0b51114c751900525b366991e35a542e950/modules/effects/src/passes/postprocessing/image-adjust-filters/denoise.ts#L18)
- (probably more)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 05:08](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395296760):
[vello](https://github.com/linebender/vello)
- [custom #import implementation](https://github.com/linebender/vello/blob/15082ba70a2f8504876dcca3c1c4667e0dc51fa5/vello_shaders/shader/fine.wgsl#L21)
- [custom #ifdef implementation](https://github.com/linebender/vello/blob/15082ba70a2f8504876dcca3c1c4667e0dc51fa5/vello_shaders/shader/fine.wgsl#L62)
- no runtime injection of strings(?)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 05:45](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395303432):
[webgpu-particles](https://github.com/hsimpson/webgpu-particles/)
- a small demo with just static [wgsl files](https://github.com/hsimpson/webgpu-particles/tree/master/public/assets/shaders)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-06 06:25](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395312768):
[webgpu-marching-cubes](https://github.com/Twinklebear/webgpu-marching-cubes)
- uses WGSL `override` to inject e.g. SCAN_BLOCK_SIZE, WORKGROUP_SIZE
- some host controlled [concatenation of wgsl files](https://github.com/Twinklebear/webgpu-marching-cubes/blob/1d550a3de65ef2f8c10a89069526c5d2b8b0413b/src/marching_cubes.ts#L142)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 02:37](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395774301):
[webgpu-volume](https://github.com/AaronWatters/webgpu_volume)
- [module linking by string concatenation](https://github.com/AaronWatters/webgpu_volume/blob/3715a721c95f8e4f4bb47940e104203eef1e6d6f/lib/actions/DepthBufferRange.js#L55)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 02:54](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395787480):
[frac_gen](https://github.com/thrombe/fracgen_gpu)
- [custom import preprocessor](https://github.com/thrombe/fracgen_gpu/blob/4d0349cc82f3b1eb58c4b481a7cf4f2f10901161/src/shader_importer.rs#L59)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 02:55](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395788113):
[rerun](https://github.dev/rerun-io/rerun)
- [custom import preprocessor](https://github.com/rerun-io/rerun/blob/5da39a51144a1c23f08f72669ace1914bdf73bf5/crates/viewer/re_renderer/shader/point_cloud.wgsl#L7-L8)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 03:07](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395797681):
[kmeans-gpu](https://github.dev/redwarp/kmeans-gpu)
- [yet another custom import preprocessor](https://github.com/redwarp/kmeans-gpu/blob/85b8c10080cb25160709c911e237fdcd777579d7/core/shaders/mix_colors.wgsl#L19)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 04:08](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395852191):
[pixijs-filters]()
- image plugins with standard plugin uniforms and separate per plugin [uniforms](https://github.com/pixijs/filters/blob/107c936e765daa90e851faa86daf4afc1b27bd34/src/zoom-blur/zoom-blur.wgsl#L20-L21)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 04:12](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395855742):
[cell_simulation](https://github.com/javirk/cell_simulation)
- [custom import preprocessor](https://github.com/javirk/cell_simulation/blob/0cf815e1f1f5855d600f9cf656b97c6cf7d78ad4/res/shader/render_3d.wgsl#L1)
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2024-10-07 04:17](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2395859651):
[GraphWaGu](https://github.com/harp-lab/GraphWaGu)
- file per shader, [copy](https://github.com/harp-lab/GraphWaGu/blob/1d5c138b14ef3420365f2deba29aa663ebe6837e/src/wgsl/compute_attractive_new.wgsl#L1) [paste](https://github.com/harp-lab/GraphWaGu/blob/1d5c138b14ef3420365f2deba29aa663ebe6837e/src/wgsl/apply_forces.wgsl#L1C1-L8C25) for struct sharing
#### <img src="https://avatars.githubusercontent.com/u/63816?u=9e0d6ad818cbf0be7b8403e432ebe8ad585ded69&v=4" width="50">[mighdoll](https://github.com/mighdoll) commented at [2025-02-20 18:53](https://github.com/wgsl-tooling-wg/wesl-spec/issues/50#issuecomment-2672398068):
close in lieu of separate issues.