Three.js: if scene use skybox , then mesh material disable depthTest and depthWrite no show

Created on 22 Nov 2018  路  11Comments  路  Source: mrdoob/three.js

If the scene uses skybox via scene.background, it's not possible to see the mesh when depthTest and depthWrite of its materials is set to false.

envMap = new THREE.CubeTextureLoader()
.setPath( 'textures/cube/skyboxsun25deg/')
.load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );
scene.background = envMap;

var lineMaterial = new THREE.MeshBasicMaterial();
lineMaterial.color.setHex( 0xDAA520 );
material.depthTest = false;
material.depthWrite = false;

var lineGeometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
var lineEntity = new THREE.Mesh( lineGeometry, lineMaterial );
scene.add( lineEntity );

image

Three.js version
  • [x] Dev
  • [x] r98
  • [ ] ...
Browser
  • [ ] All of them
  • [x] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [ ] All of them
  • [ ] Windows
  • [x] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Bug

Most helpful comment

Perhaps the background should be rendered first.

Yeah... The fact that it renders last is supposed to be to avoid drawing pixels twice. It's a optimisation that keeps bumping into cases where it creates issues.

I agree, we should change it so it renders first. It'll be better to favour something robust better than something optimal but delicate.

All 11 comments

Fiddle for reproduction: https://jsfiddle.net/f2Lommf5/16063/

I guess you expect to see the cube although depthTest and depthWrite is set to false, right?

As a workaround, create you skybox like in this fiddle: https://jsfiddle.net/f2Lommf5/16064/

var cubeShader = THREE.ShaderLib[ 'cube' ];
cubeShader.uniforms[ 'tCube' ].value = envMap;

var skyBoxMaterial = new THREE.ShaderMaterial( {
    fragmentShader: cubeShader.fragmentShader,
    vertexShader: cubeShader.vertexShader,
    uniforms: cubeShader.uniforms,
    side: THREE.BackSide
} );

var skyBox = new THREE.Mesh( new THREE.BoxBufferGeometry( 1000, 1000, 1000 ), skyBoxMaterial );
scene.add( skyBox );

it's not possible to see the mesh when depthTest and depthWrite of its materials is set to false.

If the background is rendered last of the opaque objects, it will overwrite other scene elements rendered with depthWrite = false.

I don't think depthTest is relevant to this issue.

Perhaps the background should be rendered first.

I think the following issue is related to this one: #14006

Perhaps the background should be rendered first.

Yeah... The fact that it renders last is supposed to be to avoid drawing pixels twice. It's a optimisation that keeps bumping into cases where it creates issues.

I agree, we should change it so it renders first. It'll be better to favour something robust better than something optimal but delicate.

/ping @aardgoose Any suggestions?

Can't think of anything that isn't hacky.

We could put the background objects in the renderList before the sort process and then use renderOrder to position it relative to other objects in the list with a known high value, to allow objects to override to control ordering. Feels very fragile, but maintains the optimisation for most cases.

@aardgoose Would you be willing to try, anyway. :-)

@WestLangley should I change it so WebGLBackground renders first in the meantime?

Sure. What is your technique to achieve that?

Hmm... changing the .pop() for a .unshift() here?
And passing the transparent objects render list instead?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akshaysrin picture akshaysrin  路  3Comments

filharvey picture filharvey  路  3Comments

konijn picture konijn  路  3Comments

clawconduce picture clawconduce  路  3Comments

alexprut picture alexprut  路  3Comments