feat: Add texture repetition breaking for Standard, PBR, and OpenPBR materials#18448
Conversation
…materials Add built-in support for breaking visible texture tiling patterns using 4 techniques: - Noise Blend (2 texture fetches) - low-frequency noise-driven offset blending - Hex Tiling (3 fetches) - hex-tile grid with per-tile rotation and luminance-weighted blending - Tile Randomization (4 fetches) - per-tile random offset and mirror - Voronoi Bombing (9 fetches) - smooth Voronoi with Gaussian-weighted blending New API: - material.textureRepetitionMode (Constants.TEXTURE_REPETITION_*) - material.textureRepetitionHexTilingParams ([rotStrength, fallOff, exponent, contrast]) Implementation uses a TEXRD macro in shaders that compiles to plain texture2D/textureSample when mode is 0 (default), so there is zero overhead for existing materials. Supports WebGL (GLSL) and WebGPU (WGSL). Inspector v2 support with mode dropdown and hex tiling parameter sliders. 3 visualization tests added (Standard, PBR, OpenPBR). References: - Inigo Quilez: https://iquilezles.org/articles/texturerepetition/ - Morten S. Mikkelsen, JCGT 2022: https://jcgt.org/published/0011/03/05/ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
sebavan
left a comment
There was a problem hiding this comment.
Just wondering if this should be a material plugin instead ?
There was a problem hiding this comment.
Pull request overview
Adds a built-in “texture repetition breaking” feature to Babylon.js materials by routing key texture samples through a new TEXRD shader macro (GLSL + WGSL), exposing a new Material.textureRepetitionMode API (plus hex-tiling params), and wiring it into Inspector v2 and visualization tests.
Changes:
- Introduces new GLSL/WGSL shader include(s) implementing multiple texture anti-tiling techniques and switches many material texture samples to
TEXRD. - Adds new public Material API + engine
Constants.TEXTURE_REPETITION_*values and propagates the mode/params into Standard/PBR/OpenPBR defines + UBOs. - Adds Inspector v2 UI and three new visualization test cases/playgrounds.
Reviewed changes
Copilot reviewed 46 out of 49 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/tools/tests/test/visualization/config.json | Adds 3 visualization test entries for Standard/PBR/OpenPBR texture repetition modes. |
| packages/dev/inspector-v2/src/services/panes/properties/materialPropertiesService.tsx | Registers a new “Texture Repetition” section in the Material properties pane. |
| packages/dev/inspector-v2/src/components/properties/materials/materialProperties.tsx | Adds mode dropdown + hex-tiling parameter sliders to Inspector v2. |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/textureRepetitionFunctions.fx | New WGSL implementation of repetition-breaking sampling + TEXRD macro. |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the PBR WGSL material UBO. |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockLightmapInit.fx | Routes lightmap sampling through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/pbrBlockFinalUnlitComponents.fx | Routes emissive sampling through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the OpenPBR WGSL material UBO. |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrTransmissionLayerData.fx | Routes transmission texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrThinFilmLayerData.fx | Routes thin-film texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrSubsurfaceLayerData.fx | Routes subsurface texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrNormalMapFragment.fx | Routes OpenPBR normal map reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrFuzzLayerData.fx | Routes fuzz texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrCoatLayerData.fx | Routes coat texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrBaseLayerData.fx | Routes base/specular/etc texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrAmbientOcclusionData.fx | Routes AO texture reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/defaultUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the default WGSL material UBO. |
| packages/dev/core/src/ShadersWGSL/ShadersInclude/bumpFragment.fx | Routes bump map reads through TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/pbr.fragment.fx | Includes textureRepetitionFunctions and switches multiple samplings to TEXRD (WGSL). |
| packages/dev/core/src/ShadersWGSL/default.fragment.fx | Includes textureRepetitionFunctions and switches multiple samplings to TEXRD (WGSL). |
| packages/dev/core/src/Shaders/ShadersInclude/textureRepetitionFunctions.fx | New GLSL implementation of repetition-breaking sampling + TEXRD macro. |
| packages/dev/core/src/Shaders/ShadersInclude/pbrVertexDeclaration.fx | Adds vTextureRepetitionHexTilingParams uniform declaration (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/pbrUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the PBR GLSL material UBO. |
| packages/dev/core/src/Shaders/ShadersInclude/pbrBlockLightmapInit.fx | Routes lightmap sampling through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/pbrBlockFinalUnlitComponents.fx | Routes emissive sampling through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrVertexDeclaration.fx | Adds vTextureRepetitionHexTilingParams uniform declaration (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the OpenPBR GLSL material UBO. |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrTransmissionLayerData.fx | Routes transmission texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrThinFilmLayerData.fx | Routes thin-film texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrSubsurfaceLayerData.fx | Routes subsurface texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragment.fx | Routes OpenPBR normal map reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrFuzzLayerData.fx | Routes fuzz texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrCoatLayerData.fx | Routes coat texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrBaseLayerData.fx | Routes base/specular/etc texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/openpbrAmbientOcclusionData.fx | Routes AO texture reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/defaultVertexDeclaration.fx | Adds vTextureRepetitionHexTilingParams uniform declaration (GLSL). |
| packages/dev/core/src/Shaders/ShadersInclude/defaultUboDeclaration.fx | Adds vTextureRepetitionHexTilingParams to the default GLSL material UBO. |
| packages/dev/core/src/Shaders/ShadersInclude/bumpFragment.fx | Routes bump map reads through TEXRD (GLSL). |
| packages/dev/core/src/Shaders/pbr.fragment.fx | Includes textureRepetitionFunctions and switches multiple samplings to TEXRD (GLSL). |
| packages/dev/core/src/Shaders/openpbr.fragment.fx | Includes textureRepetitionFunctions and switches multiple samplings to TEXRD (GLSL). |
| packages/dev/core/src/Shaders/default.fragment.fx | Includes textureRepetitionFunctions and switches multiple samplings to TEXRD (GLSL). |
| packages/dev/core/src/Materials/standardMaterial.ts | Adds TEXTURE_REPETITION_MODE define + UBO param upload for StandardMaterial. |
| packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts | Adds TEXTURE_REPETITION_MODE define + UBO param upload for PBRBaseMaterial. |
| packages/dev/core/src/Materials/PBR/openpbrMaterial.ts | Adds TEXTURE_REPETITION_MODE define + UBO param upload for OpenPBRMaterial. |
| packages/dev/core/src/Materials/material.ts | Introduces textureRepetitionMode + textureRepetitionHexTilingParams API + serialization. |
| packages/dev/core/src/Engines/constants.ts | Adds new Constants.TEXTURE_REPETITION_* values. |
It's not possible, we have to patch all texture reads. We can't do that with a material plugin. |
- Validate/clamp textureRepetitionMode to 0-4 in setter - Fix Noise Blend to preserve alpha channel (blend vec4, not vec3) - Fix fetch count docs: Noise Blend is 3 fetches, not 2 - Force textureRepetitionMode to 0 on WebGL1 (textureGrad not available) - Add excludedEngines: [webgl1] to visualization tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18448/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
|
You have changed file(s) that made possible changes to the sandbox. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18448/merge/ |
|
You have made possible changes to the playground. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18448/merge/ The snapshot playground with the CDN snapshot (only when available): Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly. |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results❌ Failed Tests (4)
|
…contexts Shared shader includes (bumpFragment, pbrBlockLightmapInit, pbrBlockFinalUnlitComponents) may be included by Node Material or other contexts that don't include textureRepetitionFunctions.fx. Add #ifndef TEXRD fallback to plain texture2D/textureSample in both GLSL and WGSL versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bumpFragment.fx, pbrBlockLightmapInit.fx, and pbrBlockFinalUnlitComponents.fx are shared with Node Material which uses regex to replace sampler names. Using TEXRD in these includes breaks NME's regex patterns (e.g. texture.+?bumpSampler). Reverted these shared includes to use plain texture2D/textureSample. TEXRD remains in material-specific shaders (default.fragment.fx, pbr.fragment.fx, openpbr.fragment.fx) and OpenPBR-only includes which are never used by NME. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
- Restore TEXRD in bumpFragment.fx, pbrBlockLightmapInit.fx, and pbrBlockFinalUnlitComponents.fx (both GLSL and WGSL) so bump, lightmap, and emissive textures benefit from repetition breaking. - Add #ifndef TEXRD fallback guards so NME (which doesn't include textureRepetitionFunctions.fx) still compiles correctly. - Update NME perturbNormalBlock.ts regexes to match both texture2D/ textureSample AND TEXRD patterns using tight alternation: (?:texture2D|TEXRD) for GLSL, (?:textureSample|TEXRD) for WGSL. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18448/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
|
You have changed file(s) that made possible changes to the sandbox. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18448/merge/ |
|
You have made possible changes to the playground. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18448/merge/ The snapshot playground with the CDN snapshot (only when available): Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Visualization tests for WebGPU |
|
You have changed file(s) that made possible changes to the sandbox. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18448/merge/ |
|
You have made possible changes to the playground. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18448/merge/ The snapshot playground with the CDN snapshot (only when available): Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly. |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
…ibility The TEXRD fallback was previously declared in shared includes that get inlined inside main() (bumpFragment.fx, pbrBlockLightmapInit.fx, pbrBlockFinalUnlitComponents.fx). WGSL doesn't allow nested function declarations, so a fallback fn TEXRD inside main() failed to compile when these includes were used by NME (which inlines them inside its generated function). Moved the fallback to module-scope includes that NME always emits at top level: bumpFragmentMainFunctions.fx for bump, pbrHelperFunctions.fx for PBR. Added #define TEXRD_DEFINED inside the fallback so the textureRepetitionFunctions include doesn't double-define when both are emitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Visualization tests for WebGPU |
|
You have changed file(s) that made possible changes to the sandbox. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18448/merge/ |
|
You have made possible changes to the playground. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18448/merge/ The snapshot playground with the CDN snapshot (only when available): Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly. |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
|
WebGL2 visualization test reporter: |
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
…pers The fallback TEXRD definitions in pbrHelperFunctions.fx and bumpFragmentMainFunctions.fx now set TEXRD_DEFINED. To prevent the shader's textureRepetitionFunctions include from then re-defining TEXRD (GLSL: 'macro redefined' error), reorder includes so that textureRepetitionFunctions runs FIRST in default/pbr/openpbr fragment shaders. The fallback in helpers then sees TEXRD_DEFINED and skips. Also added missing #include<textureRepetitionFunctions> to ShadersWGSL/openpbr.fragment.fx (it was only present in the GLSL version). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…WGSL OpenPBR shaders WGSL doesn't have function overloading like GLSL. The openpbr WGSL shaders were calling toLinearSpace(vec3) which expects f32, causing 'type mismatch' errors at WGSL compile time. Replaced with toLinearSpaceVec3 in: - openpbrBaseLayerData.fx (base color, specular color) - openpbrCoatLayerData.fx - openpbrFuzzLayerData.fx - openpbrTransmissionLayerData.fx - openpbrIblFunctions.fx (3 sites) - openpbr.fragment.fx (emission) This is independent of the texture repetition feature but was exposed when running OpenPBR scenes through WebGPU. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18448/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18448/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
|
You have changed file(s) that made possible changes to the sandbox. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/SANDBOX/refs/pull/18448/merge/ |
|
You have made possible changes to the playground. https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/PLAYGROUND/refs/pull/18448/merge/ The snapshot playground with the CDN snapshot (only when available): Note that neither Babylon scenes nor textures are uploaded to the snapshot directory, so some playgrounds won't work correctly. |
|
WebGL2 visualization test reporter: |
|
Visualization tests for WebGPU |
🟢 Memory Leak Test Results13 passed, 0 leaked out of 13 scenarios 🟢 All memory leak tests passed — no leaks detected. Passed Scenarios (13)
|
⚡ Performance Test Results🟢 All performance tests passed — no regressions detected. |
Summary
Add built-in support for breaking visible texture tiling patterns using 4 techniques, directly in Standard, PBR, and OpenPBR materials.
New API
Default is
TEXTURE_REPETITION_NONE(0) — zero overhead,TEXRDmacro compiles to plaintexture2D/textureSample.Techniques
Implementation
TEXRDmacro in a new shader include replacestexture2D/textureSamplecalls for all tiling surface texturesTEXRDcompiles to plaintexture2D/textureSample— zero costMaterialbase class, available to all material typesVisualization Tests
3 new tests added, one per material type (Standard, PBR, OpenPBR), each showing 4 ground planes with the 4 repetition modes.
Demo Playground
https://playground.babylonjs.com/#7XUUXW#0
Documentation
Documentation will follow once the PR is merged.