# Transparent mesh material with (needAlphaBlending=true) miss depth rendering order with particles

**URL:** <https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116>\
**Category:** Questions\
**Tags:** particles, mesh\
**Created:** [March 14, 2025, 1:20am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116 "2025-03-14T01:20:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Khanon](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/khanon/32/14980_2.png) [@Khanon](https://forum.babylonjs.com/u/Khanon)\
**Post date:** [March 14, 2025, 1:20am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/1 "2025-03-14T01:20:20Z")

</div>

Hello,

I create a particle (white square texture) that should be nearer to the camera than a plain mesh (_Sprite - ./assets/background.png_ node), but the particle renders behind the mesh.

Some idea why is this happening?

Camera position: `-380, 0, 0.001`  
Camera target: `1, 0, 0`  
Particle position: `0, 0, -10`  
Mesh position: `1000, 0, 90`

Link to the test: [Khanon.js 04 Loading 2D sprites and particles](https://khanonjs.com/test/)  
`Ctrl + Alt + Shift + I` → Info of the scene.

The mesh’s texture is rendered by a custom shader material, in case that can be the reason.  
Am I missing some transformation in the material?

```auto
BABYLON.Effect.ShadersStore[`spriteMesh${this.idShader}VertexShader`] = `
    precision highp float;
    attribute vec3 position;
    attribute vec2 uv;
    uniform mat4 worldViewProjection;
    varying vec2 vUv;

    void main() {
        vec4 p = vec4(position, 1.);
        gl_Position = worldViewProjection * p;
        vUv = uv;
    }
`
    BABYLON.Effect.ShadersStore[`spriteMesh${this.idShader}FragmentShader`] = `
    precision highp float;
    varying vec2 vUv;
    uniform sampler2D textureSampler;
    uniform int frame;
    uniform float alpha;

    void main() {
        int uOffset = frame % ${this.numCols};
        int vOffset = frame / ${this.numCols};
        vec2 computedUV = vec2(vUv.x * ${this.propCol.toPrecision(7)} + float(uOffset) * ${this.propCol.toPrecision(7)}, vUv.y * ${this.propRow.toPrecision(7)} + float(vOffset) * ${this.propRow.toPrecision(7)});
        vec4 color = texture2D(textureSampler, computedUV);
        gl_FragColor = vec4(color.rgb, alpha * color.a);
    }
`

const shaderMaterial = new BABYLON.ShaderMaterial(`spriteMaterial-${this.name}`, this.babylon.scene, `spriteMesh${this.idShader}`, {
      attributes: ['position', 'uv'],
      uniforms: ['worldViewProjection'],
      samplers: ['textureSampler'],
      needAlphaBlending: true
    })

```

---

<div class="post-metadata">

**Author:** ![Tricotou](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/tricotou/32/5844_2.png) [@Tricotou](https://forum.babylonjs.com/u/Tricotou)\
**Post date:** [March 14, 2025, 9:44am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/2 "2025-03-14T09:44:22Z")

</div>

Hello @Khanon , maybe your custom shader is breaking some depth check…  
Could you setup a repro on a playground so that we can have a look ? 🙂

---

<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:** [March 14, 2025, 10:03am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/3 "2025-03-14T10:03:32Z")

</div>

Your meshes (materials) are transparent, and transparent objects are rendered last, after the particle systems.

I think you set `needAlphaBlending:true` to the shader materials? As your meshes don’t seem to be transparent, you should remove this setting. If the materials must be transparent, you can set the `renderingGroupId` property of the particle system to 1, so that it is drawn after the transparent meshes.

---

<div class="post-metadata">

**Author:** ![Khanon](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/khanon/32/14980_2.png) [@Khanon](https://forum.babylonjs.com/u/Khanon)\
**Post date:** [March 14, 2025, 10:22am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/4 "2025-03-14T10:22:46Z")

</div>

You are absolutelly right, it is the `needAlphaBlending:true` property.

I can handle it now, I change the post title to something more explanatory about what have caused the issue.

Thanks!!

---

<div class="post-metadata">

**Author:** ![Khanon](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/khanon/32/14980_2.png) [@Khanon](https://forum.babylonjs.com/u/Khanon)\
**Post date:** [March 14, 2025, 11:36am UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/5 "2025-03-14T11:36:39Z")

</div>

`needAlphaBlending` needs to be `true` to allow drawing `.pngs` on the mesh and respect the alpha channel.

I will have to set the `renderingGroupId` of particles to a high value by default, so particles will be always drawn after the mesh sprites.

This isn’t an optiaml solution because particles wont have a proper deph distribution, but I don’t figure out a better way to do it ☹

If I don’t set `needAlphaBlending` to `true`, the material textures are rendered like this:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/0/c/0c027c19dc125bcb4db71cb9cb42dc38b01ae010.png)

instead of this:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/5/2/523ae1b5f6548e0e07254a62ffad4c6f55c31259.jpeg)

---

<div class="post-metadata">

**Author:** ![Khanon](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/khanon/32/14980_2.png) [@Khanon](https://forum.babylonjs.com/u/Khanon)\
**Post date:** [March 14, 2025, 1:16pm UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/9 "2025-03-14T13:16:10Z")

</div>

`renderingGroupId` is the only solution?

This is a problem in the engine ☹

All sprite meshes need to support alpha blending to allow `.png` textures with alpha channel.

Setting a `renderingGroupId` high value by default for particles will drive to wrong depth distribution in many cases.

Forcing the user to set the `renderingGroupId` for all the created particles is complex to implement in a game with tons of elements.

Is there something I can do with the shader material or whatever to have a proper depth distribution using transparent meshes and particles?

---

<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:** [March 14, 2025, 2:36pm UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/10 "2025-03-14T14:36:00Z")

</div>

Particles are not sorted, it would take too much time, and a particle system is rendered as a single draw call, for performance reason too. So, it’s not possible to interleave the rendering of meshes/sprites with the rendering of the particles of a particle system. You can only decide to render sprites/meshes before/after the particle systems by using the `renderingGroupId` property of meshes/spritees/particle systems.

> [@Khanon](#):
>
> Setting a `renderingGroupId` high value by default for particles will drive to wrong depth distribution in many cases.

Transparent objects (meshes, sprites, particles) do not write in the depth buffer, so they do not occlude themselves and they are all blended up. Drawing them in the wrong depth order is often not very visible, but of course it depends on your scene. Unfortunately, this is something we can’t do much about; it’s a well-known problem with [transparent objects](https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering/).

---

<div class="post-metadata">

**Author:** ![Tricotou](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/tricotou/32/5844_2.png) [@Tricotou](https://forum.babylonjs.com/u/Tricotou)\
**Post date:** [March 14, 2025, 3:10pm UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/11 "2025-03-14T15:10:48Z")

</div>

Following what @Evgeni_Popov said, here is a PG to run some occlusion tests with transparent mesh + particles :

![Screencast from 14-03-2025 16:08:18](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/3/b/3b60e4cdaad9295e28e92a106e81a5e3439a9dee.gif)

> **[Babylon.js Playground](https://playground.babylonjs.com/#4U4QH9%23224)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL and WebGPU 3D scenes

---

<div class="post-metadata">

**Author:** ![Khanon](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/khanon/32/14980_2.png) [@Khanon](https://forum.babylonjs.com/u/Khanon)\
**Post date:** [March 14, 2025, 3:34pm UTC](https://forum.babylonjs.com/t/transparent-mesh-material-with-needalphablending-true-miss-depth-rendering-order-with-particles/57116/12 "2025-03-14T15:34:10Z")

</div>

Thanks for your time explaining it.

`rederingGroupId` will be a required property in particles definition.

- For 3D games the user can set `rederingGroupId=0` and ignore it.

- For 2D games the user will be required to set the `rederingGroupId` to a value higher than the sprite behind it (normally the whole scene).
