Skip to content

fix(particles): use mesh UVs when texturing mesh particles (#7858)#8931

Merged
mvaligursky merged 1 commit into
mainfrom
mv-particle-mesh-uv
Jun 19, 2026
Merged

fix(particles): use mesh UVs when texturing mesh particles (#7858)#8931
mvaligursky merged 1 commit into
mainfrom
mv-particle-mesh-uv

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Fixes mesh particles ignoring their mesh UVs, so a colorMap texture now maps across the mesh instead of rendering as a flat single-texel color. Regression from the particle shader generator refactor; reported in #7858.

Root cause:

  • The GPU particle vertex buffer stored the mesh UV under the SEMANTIC_ATTR1 semantic. As a result the particle mesh instance never reported SHADERDEF_UV0, so ParticleMaterial's meshUv option (objDefs & SHADERDEF_UV0) was always false.
  • With meshUv off, USE_MESH_UV was not defined and particle_uv fell back to a constant vec2(0.0), so every particle sampled a single texel. Even if forced on, particle_uv (mapped to TEXCOORD0, location 5) did not match the vertex buffer's ATTR1 (location 1).

Changes:

  • Store the mesh UV under SEMANTIC_TEXCOORD0 in ParticleEmitter.getVertexInfo(). This makes the particle mesh instance report SHADERDEF_UV0, which both enables the USE_MESH_UV shader path and binds particle_uv at the matching attribute location.
  • Fixes both WebGL2 and WebGPU (shared shader generator); the CPU particle path is unaffected (it packs UVs separately via ATTR4).

Examples:

  • Added a "Textured" toggle to the Particles Mesh example that applies a color map to the mesh particles, demonstrating the mesh UVs are used.

GPU mesh particles ignored the mesh UVs, so a colorMap rendered as a flat
single-texel color. The particle vertex buffer stored the mesh UV under the
SEMANTIC_ATTR1 semantic, so the particle mesh instance never reported
SHADERDEF_UV0. That disabled the meshUv shader path (particle_uv fell back to
a constant vec2(0.0)) and, even when forced on, bound particle_uv at a location
that did not match the vertex buffer.

Storing the UV under SEMANTIC_TEXCOORD0 makes the mesh instance report
SHADERDEF_UV0, which enables USE_MESH_UV and binds particle_uv at the matching
attribute location. Fixes WebGL2 and WebGPU; the CPU path is unaffected.

Also adds a "Textured" toggle to the particles-mesh example.
@github-actions

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2277.3 KB — 584.8 KB (−0.0 KB, −0.00%) 454.7 KB (+0.1 KB, +0.01%)
playcanvas.min.mjs 2274.7 KB — 583.9 KB (−0.0 KB, −0.00%) 454.1 KB (−0.0 KB, −0.01%)

@mvaligursky mvaligursky requested a review from Copilot June 19, 2026 13:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@mvaligursky mvaligursky merged commit 868a87c into main Jun 19, 2026
10 checks passed
@mvaligursky mvaligursky deleted the mv-particle-mesh-uv branch June 19, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants