Question
Is there a significant difference between depthWrite: false
and depthTest: false
? Does using depthTest
offer a performance advantage? Is there any sacrifice in functionality choosing one or the other?
Original problem
I wanted to render a THREE.Points
object with translucent circles as each point. I used a THREE.Texture
loaded from a canvas
element and passed it to the map
property on the THREE.PointsMaterial
.
The transparency did not completely work, some circles overlapped fine but others behaved as if they were solid.
I fixed it after learning about depthWrite: false
and depthTest: false
on the THREE.PointsMaterial
.
Where I'm at
I have a code example (embedded at bottom) that shows the overlapping points error, and can use depthTest
or depthWrite
to fix it:
var points = new THREE.Points(
new THREE.Geometry(),
new THREE.PointsMaterial({
//depthTest: false,
//depthWrite: false,
map: circleTexture,
size: circleDiameter,
transparent: true
})
);
I'm new to all this, but I tried reading up on the subject, and from what I can tell (correct me if I'm wrong) the depth buffer is used to determine what fragments are occluded and do not need rendering. Turning off either depthWrite
or depthTest
will exempt an object from this process. They differ in that:
depthWrite: false
still calculates depth, but renders the entire object regardlessdepthTest: false
does not even calculate depth
So it sounds like I would lose some object qualities by turning off depthTest
instead of depthWrite
, but possibly get a performance boost by skipping the calculation altogether? But, what qualities would I be losing? And is there actually a performance difference? Here my ignorance shines through.
// Sizes
var sceneWidth = 200;
var sceneHeight = 200;
var lineLength = 50;
var circleRadius = 32;
var circleDiameter = circleRadius * 2;
// Renderer
var renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(sceneWidth, sceneHeight);
document.body.appendChild(renderer.domElement);
// Scene
var scene = new THREE.Scene();
// Camera
var d = 100;
var aspect = sceneWidth / sceneHeight;
var camera = new THREE.OrthographicCamera(
-d * aspect,
d * aspect,
d,
-d,
1,
12000
);
camera.position.set(140, 140, 140);
scene.add(camera);
// Controls
var controls = new THREE.OrthographicTrackballControls(
camera,
renderer.domElement
);
controls.rotateSpeed = 0.2;
controls.addEventListener('change', function () {
renderer.render(scene, camera);
});
window.addEventListener('resize', function() {
controls.handleResize();
});
// Circle texture
var canvasEl = document.createElement('canvas');
var context = canvasEl.getContext('2d');
canvasEl.width = circleDiameter;
canvasEl.height = circleDiameter;
context.fillStyle = 'rgba(255, 255, 255, 0.5)';
context.beginPath();
context.arc(circleRadius, circleRadius, circleRadius, 0, Math.PI * 2);
context.fill();
var circleTexture = new THREE.Texture(canvasEl);
circleTexture.needsUpdate = true;
// Points
var points = new THREE.Points(
new THREE.Geometry(),
new THREE.PointsMaterial({
//depthTest: false,
//depthWrite: false,
map: circleTexture,
size: circleDiameter,
transparent: true
})
);
points.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
points.geometry.vertices.push(new THREE.Vector3(0, lineLength, 0));
points.geometry.vertices.push(new THREE.Vector3(0, lineLength, lineLength));
points.geometry.vertices.push(new THREE.Vector3(0, 0, lineLength));
scene.add(points);
// Lines
var lines = new THREE.Line(
new THREE.Geometry(),
new THREE.LineBasicMaterial({
linewidth: 1.2,
color: 0xffffff,
transparent: true,
opacity: 0.25
})
);
lines.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
lines.geometry.vertices.push(new THREE.Vector3(0, lineLength, 0));
lines.geometry.vertices.push(new THREE.Vector3(0, lineLength, 0));
lines.geometry.vertices.push(new THREE.Vector3(0, lineLength, lineLength));
lines.geometry.vertices.push(new THREE.Vector3(0, lineLength, lineLength));
lines.geometry.vertices.push(new THREE.Vector3(0, 0, lineLength));
lines.geometry.vertices.push(new THREE.Vector3(0, 0, lineLength));
lines.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
scene.add(lines);
// Render
function render() {
window.requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
}
render();
* { margin: 0; padding: 0; }
body { background-color: #333; }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Document</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r76/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrthographicTrackballControls.js"></script>
</body>
</html>