4

I am seeing a problem with inconsistent rendering of transparent objects in three.js and I can't quite figure out what is happening there and what causes the problem.

A reduced test-case to demonstrate the issue can be found here: http://jsfiddle.net/fgu0fzro/3/.

The important bits:

renderer.setClearColor(0xffffff);

camera = new THREE.PerspectiveCamera(50, aspectRatio, 1, 1000000);
camera.position.set( 4600, 4800, -10000);

cameraControl = new THREE.OrbitControls( camera, renderer.domElement );

var plane = new THREE.Mesh(
    new THREE.PlaneGeometry(100000,100000),
    new THREE.MeshLambertMaterial({
        color: 0x2B79DE, transparent:true, opacity:.75
    })
);

var cube = new THREE.Mesh(
  new THREE.BoxGeometry(1000,1000,1000),
  new THREE.MeshLambertMaterial({
      color: 0xF33856, transparent: true, opacity: .2
  })
);

plane.rotation.x = -Math.PI/2;    
cube.position.set(3000, 1000, 2000);

scene.add(camera);
scene.add(plane);
scene.add(cube);

So the cube is above the plane and i'd expect to see the plane through the transparent cube. Instead, it is rendered as if the plane wasn't there at all. Now, if you move the camera slightly to the left, the problem disappears and everything gets rendered like it should.

Now, I already figured out that this problem has to do with the object sorting of three.js (if i set renderer.sortObjects = false; and add the objects in the proper order, it works), but I still don't quite unterstand what exactly is happening there and i wonder if there is any way to solve this without disabling the otherwise useful object-sorting.

three.js r70

WestLangley
  • 102,557
  • 10
  • 276
  • 276
Martin Schuhfuß
  • 6,814
  • 1
  • 36
  • 44

1 Answers1

2

Alpha-blending of transparent objects in three.js is not order-independent -- in other words, the order in which the objects are rendered will impact the result.

Also, material.depthTest and material.DepthWrite values will affect the result. By default, they are both true. You can experiment with changing them, but there may be unwanted side-effects depending on your use case.

In your particular case, I would have two scenes and implement two render passes. The first scene would contain the plane, and the second scene would contain the remaining objects. See this answer.

three.js r.70

Community
  • 1
  • 1
WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • so, from what i already figured out, the order in which my two elements are drawn varies depending on the camera orientation. This seems a bit odd since the actual geometry by which ordering should happen ideally doesn't change. The `depthTest` and `depthWrite`-properties unfortunately don't really help. Is creating multiple scenes something that is recommended to do in these cases? – Martin Schuhfuß Feb 16 '15 at 16:40
  • 2
    1. Transparent objects in three.js are rendered based on their distance from the camera. You are changing the camera position. 2. Google webGL and transparency to learn more about the issues. 3. Multiple render passes is an option available in your toolkit. – WestLangley Feb 16 '15 at 17:15