Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

three.js - Overlapping layers flickering

Tags:

three.js

When several objects overlap on the same plane, they start to flicker. How do I tell the renderer to put one of the objects in front?

I tried to use .renderDepth, but it only works partly - see example here:
http://liveweave.com/ahTdFQ
Both boxes have the same size and it works as intended. I can change which of the boxes is visible by setting .renderDepth. But if one of the boxes is a bit smaller (say 40,50,50) the contacting layers are flickering and the render depth doesn't work anymore.

How to fix that issue?

like image 245
Miiller Avatar asked Aug 06 '14 15:08

Miiller


2 Answers

When .renderDepth() doesn't work, you have to set the depths yourself.

Moving whole meshes around is indeed not really efficient.
What you are looking for are offsets bound to materials:

material.polygonOffset = true;
material.polygonOffsetFactor = -0.1;

should solve your issue. See update here: http://liveweave.com/syC0L4
Use negative factors to display and positive factors to hide.

like image 148
Miiller Avatar answered Jan 14 '23 23:01

Miiller


Try for starters to reduce the far range on your camera. Try with 1000. Generally speaking, you shouldn't be having overlapping faces in your 3d scene, unless they are treated in a VERY specific way (look up the term 'decal textures'/'decals'). So basically, you have to create depth offsets, and perhaps even pre sort the objects when doing this, which all requires pretty low-level tinkering.

If the far range reduction helps, then you're experiencing a lack of precision (depending on the device). Also look up 'z fighting'

UPDATE

Don't overlap planes.

How do I tell the renderer to put one of the objects in front?

You put one object in front of the other :)

For example if you have a camera at 0,0,0 looking at an object at 0,0,10, if you want another object to be behind the first object put it at 0,0,11 it should work.

UPDATE2

What is z-buffering:

http://en.wikipedia.org/wiki/Z-buffering http://msdn.microsoft.com/en-us/library/bb976071.aspx

Take note of "floating point in range of 0.0 - 1.0".

What is z-fighting: http://en.wikipedia.org/wiki/Z-fighting

...have similar values in the z-buffer. It is particularly prevalent with coplanar polygons, where two faces occupy essentially the same space, with neither in front. Affected pixels are rendered with fragments from one polygon or the other arbitrarily, in a manner determined by the precision of the z-buffer.

"The renderer cannot reposition anything."

I think that this is completely untrue. The renderer can reposition everything, and probably does if it's not shadertoy, or some video filter or something. Every time you move your camera the renderer repositions everything (the camera is actually the only thing that DOES NOT MOVE).

It seems that you are missing some crucial concepts here, i'd start with this: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

About the depth offset mentioned:

How this would work, say you want to draw a decal on a surface. You can 'draw' another mesh on this surface - by say, projecting a quad onto it. You want to draw a bullet hole over a concrete wall and end up with two coplanar surfaces - the wall, the bullet hole. You can figure out the depth buffer precision, find the smallest value, and then move the bullet hole mesh by that value towards the camera. The object does not get scaled (you're doing this in NDC which you can visualize as a cube and moving planes back and forth in the smallest possible increment), but does translate in depth direction, ending up in front of the other.

like image 25
pailhead Avatar answered Jan 15 '23 01:01

pailhead