# Uniform arrays with non uniform control texture sample (WebGPU)

**URL:** <https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252>\
**Category:** Bugs\
**Tags:** shader, webgpu, glsl\
**Created:** [December 7, 2023, 2:17pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252 "2023-12-07T14:17:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 7, 2023, 2:17pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/1 "2023-12-07T14:17:45Z")

</div>

Hello everyone!

This is a followup question to [Texture sampler and non uniform control flow](https://forum.babylonjs.com/t/texture-sampler-and-non-uniform-control-flow/46084)

TLDR: uniform control flow analysis can be disabled in BabylonJS by adding `/* disable_uniformity_analysis */` in the shader code.

The story could have ended here, and my code would be compatible with WebGPU (I am almost there I swear) but I finally managed to reproduce a very weird bug that is related to this non uniform analysis.

Here is a PG that can produce the bug: [https://www.babylonjs-playground.com/#1PHYB0#329](https://www.babylonjs-playground.com/#1PHYB0#329)

To make the bug happen, you only need to uncomment line 112, which is a non uniform texture sample.

Normally this would not be an issue as I marked the shader as to ignore these non uniformities, but _somehow_, because I referenced an array of uniforms (here this is `uniform vec3 lightPositions[2];`), it creates this weird error of type alias:

```auto
WebGPU uncaptured error (1): [object GPUValidationError] - Tint WGSL reader failure: :2:13 error: invalid type alias
alias Arr = @stride(16) array<vec3<f32>, 2u>;

```

Indeed, when I remove the reference to the uniform array (PG: [https://www.babylonjs-playground.com/#1PHYB0#330](https://www.babylonjs-playground.com/#1PHYB0#330)), the bug goes away 🤔

I haven’t the faintest idea about why this is happening, if anyone can help, it would be much appreciated 🙏

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 7, 2023, 3:40pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/2 "2023-12-07T15:40:46Z")

</div>

It may be because we are not using the latest version of Tint, because it is too big (two times bigger than the version we use!). We are waiting for the file to come back to a smaller size before we update our TintWASM package (they currently have two code paths and they are going to remove one, that’s why it is so big).

In your case, you can fix the problem by using `textureLod` instead of `texture2D`:

> **[Babylon.js Playground](https://www.babylonjs-playground.com/#1PHYB0%23331)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

Or use `textureGrad`, if you still want trilinear mipmapping:

> **[Babylon.js Playground](https://www.babylonjs-playground.com/#1PHYB0%23332)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

However, the default sampling mode for a post process is “nearest”, meaning no mipmaps are generated. If you want mipmaps, you will have to pass `BABYLON.Constants.TEXTURE_TRILINEAR_SAMPLINGMODE` for `samplingMode` when creating the post-process.

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 7, 2023, 7:51pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/3 "2023-12-07T19:51:38Z")

</div>

Thank you for the insights!

The solution with `textureGrad` does not work when the calls to `dFdx` and `dFdy` are inside a non uniform control flow: [https://www.babylonjs-playground.com/#1PHYB0#334](https://www.babylonjs-playground.com/#1PHYB0#334) It is probably also related to the TintWASM version.

`textureLod` does work indeed, but the loss of the trilinear mipmapping is a bummer and murders the image quality 😕 (and also the performance)

Is there a way to override the version of TintWASM used by BabylonJS? The file size is not really an issue for me in the development process.

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [December 7, 2023, 8:13pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/4 "2023-12-07T20:13:38Z")

</div>

In this case you could also move the derivatives call out of the condition: [https://www.babylonjs-playground.com/#1PHYB0#335](https://www.babylonjs-playground.com/#1PHYB0#335)

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 7, 2023, 8:39pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/5 "2023-12-07T20:39:03Z")

</div>

Indeed it works, I think it is equivalent to what @Evgeni_Popov proposed earlier, but some of my use cases prevent this solution unfortunately.

For example in my atmosphere shader ([https://github.com/BarthPaleologue/volumetric-atmospheric-scattering/blob/main/src/glsl/atmosphericScattering.glsl](https://github.com/BarthPaleologue/volumetric-atmospheric-scattering/blob/main/src/glsl/atmosphericScattering.glsl)), I would like to sample a look up texture inside the `calculateLight` function to make it _way_ faster. If I needed to somehow extract the texture coordinates all the way up the call hierarchy to find myself in a uniform control flow, it would make the code a mess, take a lot of time and could actually be infeasable 🤔

If the new lighter version of TintWASM releases in a matter of weeks I can totally wait for it, but if it takes longer I would be interested in maybe overriding the version of TintWASM I use in my projects

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [December 7, 2023, 10:57pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/6 "2023-12-07T22:57:02Z")

</div>

you can pass both the js and wasm url as an option in the webgpuengineOptions:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/b/7/b7efa70c9c2d763c7b062a3a8f619e05216cc8ae.png)

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 7, 2023, 11:54pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/7 "2023-12-07T23:54:45Z")

</div>

> [@CrashMaster](#):
>
> The solution with `textureGrad` does not work when the calls to `dFdx` and `dFdy` are inside a non uniform control flow

Yes, see my PG, it must be done before the `if`.

> [@CrashMaster](#):
>
> `textureLod` does work indeed, but the loss of the trilinear mipmapping is a bummer and murders the image quality 😕 (and also the performance)

Do it with `textureGrad`, there’s no perf problem by doing the dFdx and dFdy outside the `if`, these are fast functions.

Also, I don’t see why `textureLod` would lead to poorer performance… It does a bilinear instead of a trilinear filtering, so it should be faster on the contrary…

> [@CrashMaster](#):
>
> Is there a way to override the version of TintWASM used by BabylonJS? The file size is not really an issue for me in the development process.

You can try to get the project locally and regenerate the .wasm yourself:

> **[GitHub - BabylonJS/twgsl](https://github.com/BabylonJS/twgsl)**
>
> Contribute to BabylonJS/twgsl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 8, 2023, 7:48am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/8 "2023-12-08T07:48:53Z")

</div>

oooh nice! I will try that to rebuild the wasm and use the engine option.

> [@Evgeni\_Popov](#):
>
> Yes, see my PG, it must be done before the `if`.

I am sorry, my post was not super clear about `textureGrad`. It does work when outside the if, but in my shaders, putting the `dFdx` and `dFdy` outside will either lead to messy refactorings, and in the case of the atmosphere look up texture, it is just not possible as the `dFdx` initially be inside a for loop inside a function inside an `if`.

> [@Evgeni\_Popov](#):
>
> Also, I don’t see why `textureLod` would lead to poorer performance… It does a bilinear instead of a trilinear filtering, so it should be faster on the contrary…

Yeah I am not sure either, but it’s is really noticable, I went from 60fps to 10fps when using 10 texture samples in an evolution of the playground shader (with triplanar normal mapping which increases the number of samples quite fast).

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 8, 2023, 9:58am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/9 "2023-12-08T09:58:50Z")

</div>

> [@CrashMaster](#):
>
> Yeah I am not sure either, but it’s is really noticable, I went from 60fps to 10fps

It could be that the textures are mostly sampled with low mips when using trilinear, whereas when using `textureLod`, it always samples the mip #0, which does not play well with texture cache…

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 11, 2023, 9:14am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/10 "2023-12-11T09:14:37Z")

</div>

I have been trying to build the wasm from source today and encountered an error.

I used a Ubuntu 22.04 VM created only for this purpose.

My error happened at step 5 when running `emcmake cmake ../twgsl`:

```auto
CMake Error at CMakeLists.txt:9 (target_compile_options):
  Cannot specify compile options for target "tint_api" which is not built by
  this project.

```

I cloned all the repos in a folder called `TintWASM`. I had no error in previous steps beside not having the `python` command, which was fixed by installing pyenv.

Here is my path:

```auto
/home/barth/Documents/TintWASM/depot_tools:
/home/barth/Documents/TintWASM/emsdk:
/home/barth/Documents/TintWASM/emsdk/upstream/emscripten:
/home/barth/Documents/TintWASM/emsdk/node/16.20.0_64bit/bin:
/home/barth/.pyenv/versions/3.11.7/bin:
/home/barth/.pyenv/libexec:
/home/barth/.pyenv/plugins/python-build/bin:
/home/barth/.pyenv/plugins/pyenv-virtualenv/bin:
/home/barth/.pyenv/plugins/pyenv-update/bin:
/home/barth/.pyenv/plugins/pyenv-doctor/bin:
/home/barth/.pyenv/shims:
/home/barth/.pyenv/bin:
/home/barth/Documents/TintWASM/depot_tools:
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:
/usr/games:
/usr/local/games:
/snap/bin

```

Maybe someone got a similar error in the past?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 11, 2023, 10:28am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/11 "2023-12-11T10:28:50Z")

</div>

Maybe @Cedric will be able to help here.

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [December 11, 2023, 10:49am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/12 "2023-12-11T10:49:32Z")

</div>

I’ve just tried to kick a build and got this:

```auto
Error: Command 'python3 build/mac_toolchain.py' returned non-zero exit status 1 in /Users/runner/work/twgsl/twgsl/Dependencies/tint/.
Traceback (most recent call last):
  File "/Users/runner/work/twgsl/twgsl/Dependencies/tint/build/mac_toolchain.py", line 23, in <module>
    import pkg_resources
ModuleNotFoundError: No module named 'pkg_resources'

```

> <https://github.com/BabylonJS/twgsl/actions/runs/7166229009/job/19509792679>

I’ll take a look why it happens.

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [December 11, 2023, 12:24pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/13 "2023-12-11T12:24:59Z")

</div>

I’ve fixed the Python package thing and build went well:

> <https://github.com/BabylonJS/twgsl/actions/runs/7166414821>

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 11, 2023, 1:10pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/14 "2023-12-11T13:10:20Z")

</div>

I trided again to do a clean install with the new version, and I still got the same error 😕

Should the `twgsl_build` folder be at the same level as `twgsl` ? This is what I understood but maybe I must create it in a subfolder?

This is my file tree for the whole setup:

```auto
- ./depot_tools
- ./emsdk
- ./twgsl
- ./twgsl_build

```

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [December 11, 2023, 1:32pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/15 "2023-12-11T13:32:37Z")

</div>

yes, it looks like that.  
Is there a ‘tint\_api’ cmake target somewhere?

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 11, 2023, 1:53pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/16 "2023-12-11T13:53:24Z")

</div>

There are only 2 occurences of ‘tint\_api’:

```auto
grep -r 'tint_api' .

./twgsl/Core/twgsl/CMakeLists.txt:target_link_libraries(twgsl PRIVATE tint_api)
./twgsl/CMakeLists.txt:target_compile_options(tint_api PRIVATE -Oz)

```

I do not have a deep understanding of CMake unfortunately, I always used it in simpler cases haha  
Maybe I should try running CMake somewhere else before doing step 5?

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [December 11, 2023, 1:55pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/17 "2023-12-11T13:55:46Z")

</div>

It seems like something is missing  
is there some files in `Dependencies/tint` ?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [December 11, 2023, 2:06pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/18 "2023-12-11T14:06:20Z")

</div>

If it can help, here are the files generated by @Cedric 2 hours ago:

[TWGSL.zip](https://forum.babylonjs.com/uploads/short-url/kVZPKFSQ2zyK6JcnL3U8VqTC3o9.zip) (862.0 KB)

It uses the latest version of Tint.

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 11, 2023, 3:05pm UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/19 "2023-12-11T15:05:05Z")

</div>

Wow thank you for the wasm! I will test it soon to check if the original issue goes away 👌

> [@Cedric](#):
>
> is there some files in `Dependencies/tint` ?

Yes there are quite a few! Even though `gclient sync` failed the first time because of python, I did a clean install afterward where it succedeed directly so that should not be the issue 🤔

```auto
~/Documents/TintWASM/twgsl/Dependencies/tint$ ls -a
. .gclient_previous_sync_commits
.. .git
AUTHORS .gitignore
build .gn
BUILD.gn include
build_overrides infra
buildtools kokoro
.cipd LICENSE
.clang-format OWNERS
CMakeLists.txt PRESUBMIT.py
CMakeSettings.json README.md
CODE_OF_CONDUCT.md samples
CONTRIBUTING.md src
CPPLINT.cfg standalone.gclient
DEPS test
docs testing
Doxyfile third_party
fuzzers tint_overrides_with_defaults.gni
.gclient tools
.gclient_entries .vscode

```

---

<div class="post-metadata">

**Author:** ![CrashMaster](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/crashmaster/32/23662_2.png) [@CrashMaster](https://forum.babylonjs.com/u/CrashMaster)\
**Post date:** [December 14, 2023, 11:12am UTC](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252/20 "2023-12-14T11:12:17Z")

</div>

I imported the new Tint files in the playground here: [https://www.babylonjs-playground.com/#1PHYB0#345](https://www.babylonjs-playground.com/#1PHYB0#345)

But the bug still remains (uncommenting line 119 performs a non uniform texture sample that crashes the playground only when using a uniform array). Maybe I did something wrong with the glslang options (there is a 3rd field that I did not define as I don’t understand what it does)

Is there a way to check that the engine is indeed using the new version in this playground?

[Next page](https://forum.babylonjs.com/t/uniform-arrays-with-non-uniform-control-texture-sample-webgpu/46252.md?page=2)
