Hi all! I have a problem that’s completely stumped me that I’m hoping someone can help me fix. So for context, In my program, users control small disc shaped avatars. In reality, the disc shaped avatars are actually transparent planes using a canvas as a texture (an image is drawn to the canvas in addition to a somewhat transparent semi-circle to show orientation).
What i’m seeing happen is that the transparent parts of the plane are occluding other avatars and produce a z-fighting like effect whenever my camera is moved (e.g. flickering, phasing in/out). My camera has full 360 degree capabilities. The image and video below should show you what I mean:
The material for the plane looks something like this:
var texture = new BABYLON.DynamicTexture("dynamic texture", canvas, scene) // image is drawn to canvas
var material = new BABYLON.StandardMaterial("Mat", scene);
material.diffuseTexture = texture
material.diffuseTexture.hasAlpha = true
material.opacityTexture = material.diffuseTexture
material.transparencyMode = BABYLON.Material.MATERIAL_ALPHABLEND
material.alpha = 1
I tried to re-create the bug in a playground but i’m not sure if perhaps its the different camera setup or something else but I can’t seem to do it. Here is the playground I tried doing it in. It also shows the creation of the material in further detail: https://www.babylonjs-playground.com/#5ZCGRM#2423
I hesitate to post this considering I can’t re-create the problem in a playground and understand that that will likely make it hard to suggest any fixes but just in case this is a common issue or something that others have experienced before, i thought i would post anyway. I’m desperate
Can also confirm the flickering + occlusion happens even when the planes are not transparent. Not sure if this is just a material issue anymore
Hi there! For the transparent meshes, you could use the alphaIndex property to “manually” decide their rendering order, avoiding problems with z-fighting: Dynamic Texture Example | Babylon.js Playground (babylonjs-playground.com) - Transparent Rendering | Babylon.js Documentation (babylonjs.com)
Hi @carolhmj! thanks for the reply. I don’t know if I can assign alphaIndex property manually considering I plan to have quite a few users inside one scene who can all load in at different times. Any chance there is a property that randomly assigns unique alphaIndex on load? Or something to that effect. Sorry if these are dumb questions. I’m still a newbie.
In my humble opinion I think that two planes on the exact same level will always create flickering if they are on top of each other. I don’t know if this applies to BJS, but what if you adjust the near and far clipping plane of the camera. Less distance for the camera to consider, means more precision for rendering. In other 3D apps this has given me less flickering. Off course this depends on how much you will let the user go down on the ground and see of the horizon.
But also, cloud you not avoid this by creating round plates and apply the texture and don’t let the “chips” intersect? Polycount should not be a problem these days.
Just my two cents
hmmm perhaps I need to re-think my approach all together. Its a shame though. Thought there might be an accepted automated solution to z-fighting in babylon. A man can dream right.
No harm in asking, it’s always better than not You could simply use some kind of random number generator or even Math.random Dynamic Texture Example | Babylon.js Playground (babylonjs-playground.com)
@carolhmj thanks! Will give that a go.
@carolhmj That seemed to do the trick! Thanks so much. Just need to make sure no meshes get assigned a duplicate alphaIndex from the randomiser and should be good to go!
Instead of generating random indexes and checking for duplications, it’s simpler IMO to create a variable nextAlphaIndex and increment it each time you assign it to the next plane.
Ya incrementing does alleviate the duplicating problem. I ended up going with that in the end. Thanks @Blake
I found a far easier solution to my issue! All I had to do was disable the depthWrite on the material. I used the
material.disableDepthWrite property for those who are interested.