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: falsestill calculates depth, but renders the entire object regardlessdepthTest: falsedoes 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>