【发布时间】:2021-09-01 19:40:56
【问题描述】:
问题
depthWrite: false 和 depthTest: false 之间有显着差异吗?使用depthTest 是否提供性能优势?选择其中一种功能是否有任何牺牲?
原来的问题
我想渲染一个带有半透明圆圈的THREE.Points 对象作为每个点。我使用从canvas 元素加载的THREE.Texture 并将其传递给THREE.PointsMaterial 上的map 属性。
透明度没有完全起作用,一些圆圈重叠得很好,但其他的表现得好像它们是实心的。
我在了解THREE.PointsMaterial 上的depthWrite: false 和depthTest: false 后修复了它。
我在哪里
我有一个显示重叠点错误的代码示例(嵌入在底部),可以使用depthTest 或depthWrite 来修复它:
var points = new THREE.Points(
new THREE.Geometry(),
new THREE.PointsMaterial({
//depthTest: false,
//depthWrite: false,
map: circleTexture,
size: circleDiameter,
transparent: true
})
);
我对这一切都很陌生,但我尝试阅读该主题,并且据我所知(如果我错了,请纠正我)深度缓冲区用于确定哪些片段被遮挡并且不需要渲染。关闭depthWrite 或depthTest 将使对象免于此过程。它们的不同之处在于:
depthWrite: false仍然计算深度,但无论如何都会渲染整个对象depthTest: false甚至不计算深度
所以听起来我会通过关闭 depthTest 而不是 depthWrite 来失去一些对象质量,但可能通过完全跳过计算来提高性能?但是,我会失去什么品质?实际上是否存在性能差异?我的无知在这里闪耀。
// 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>
【问题讨论】:
标签: javascript three.js