Displacement Map bleeding couse artefacts


I wanted to understand more how to use a displacement map and how the vertex is positioned based on the map color. If I got ground subdivision: 3, do I need a map of 3x3 pixels or 4x4 pixels? so every pixel value will correspond to 1 vertex.

I made a small PG that is illustrating my bug (to see it uncomment/comment lines 48 and 49).

It looks like there is a small bleed that makes the displacement not aligned like expected. and create displaced mesh artifacts:

Displacement map


Texture Bleed:


Wrong mesh:


Expected result:

And if you can answer me this question:

If I got ground subdivision: 3, do I need a map of 3x3 pixels or 4x4 pixels? So every pixel value will correspond to 1 vertex.

Cause now I got this error and I can’t really tell.

Actually, I see that my wrong mesh is what it should be, but the 3 corners are elevated with the error. So I should have a ground mesh 3by3 and texture 4x4px for that.


But the UV scaling error is still there. And my fix is making it what it should be:



Hi Peter,

You can solve the texture bleed by changing the addressmode of the texture from the default wrap to clamp:




Thanks for replying. But I’m not talking about the bleeding of texture for the diffuse texture. I’m talking about problems with displacement.

I predict that the UV unwrapping for the displacement texture is happening in the same way as for diffuse texture, and where the bleed happens in the corner where there is that white line, the displacement read white color instead of the black, making the corners go up to value 1 instead of reading black pixel value of 0, and there is no clamping setting for the displacement.

This makes the ground plane displaced in the wrong way.

Uncomment line 48 and comment out 49 to see the displacement error, from my initial PG and this happens:


Ok, I found the problem in the CPU function that does the displacement (applyDisplacementMapFromBuffer):

It should multiply with heightMapWidth - 1 and heightMapHeight - 1 instead, because else a u or v of one will be remaindered back to zero, that’s why the four corners of your mesh are standing up – the (0, 0) pixel gets read.

Also, the uvOffset should be remaindered with 1.

Here are three demo scenes using the amiga.jpg texture:

This scene includes the original applyDisplacementMapFromBuffer function taken from babylon.max.js:


This one has the fixes applied:


This one does not have the remaindered uvOffset:


And finally your scene working as expected:


But this fix may also be a bug if the old behavior is expected, such as in the Amiga sphere examples from the PG:

Orginal: https://playground.babylonjs.com/#04JDPF#0
“Fixed”: https://playground.babylonjs.com/#04JDPF#32

Not sure how to proceed

1 Like

you rock! I’m applying the fix for next nighty ;D

thanks a ton!

1 Like

And I do not rock? (or I’m was just not mentioned) for finding it :frowning:

Just kidding :slight_smile:, but I hope I will help you with finding all that I can, and you will help me with what I need :slight_smile:



You rock too OBVIOUSLY :smiley: