背景
考虑到场景中模型顶点过多会让fps过低,所以想把相机看不到的模型从场景中移除,来提高渲染性能,但是后续测试结果让我恍然大悟。虽然场景中的顶点数降低了很多,但是每次渲染检查遮挡的过程本身就是一个消耗性能的行为,有点适得其反了。虽然并没有解决问题,但是在此做一下探索记录。
效果
例子
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry hierarchy</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background:#fff;
padding:0;
margin:0;
font-weight: bold;
overflow:hidden;
}
</style>
</head>
<body>
<!-- r58 -->
<script src="./three.js"></script>
<script type="module">
import Stats from '../jsm/libs/stats.module.js'
var container, stats, occlusionStats;
var camera, scene, renderer;
var geometry;
var mouseX = 0, mouseY = 0;
var debugMode = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'click', onDocumentClick, false );
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 10, 10000 );
camera.position.z = 500;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 1, 10000 );
var geometry = new THREE.CubeGeometry( 100, 100, 100 );
var material = new THREE.MeshNormalMaterial();
for ( var gz = -10; gz < 10 ; gz++ ) {
if ( gz % 3 === 0 ) continue;
for ( var gx = -10; gx < 10 ; gx++ ) {
if ( gx % 3 === 0 ) continue;
var height = Math.random() * 10;
for ( var gy = 0; gy < height ; gy++ ) {
var mesh = new THREE.Mesh( geometry, material );
mesh.occluder = true;
mesh.occludable = THREE.EdgeOccludable;
mesh.position.x = gx * 100;
mesh.position.y = gy * 100;
mesh.position.z = gz * 100;
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
scene.add( mesh );
}
}
}
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = true;
renderer.occlusionCulling = true;
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
window.addEventListener( 'resize', onWindowResize, false );
occlusionStats = document.createElement('DIV');
occlusionStats.style.position = 'absolute';
occlusionStats.style.top = '200px';
occlusionStats.style.zIndex = 100;
occlusionStats.style.whiteSpace = 'pre';
occlusionStats.style.fontFamily = 'monospace';
container.appendChild( occlusionStats );
var instruction = document.createElement('P');
instruction.textContent = 'Click to cycle through debug views';
instruction.style.position = 'absolute';
instruction.style.bottom = '10px';
instruction.style.zIndex = 100;
instruction.style.fontFamily = 'sans-serif';
container.appendChild( instruction );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove(event) {
mouseX = event.clientX / window.innerWidth;
mouseY = event.clientY / window.innerHeight;
}
function onDocumentClick(event) {
debugMode++;
if ( debugMode & 1 ) {
if ( ! scene.overrideMaterial ) {
scene.overrideMaterial = new THREE.MeshBasicMaterial({wireframe:true, color:0xff00ff});
}
}
else if ( scene.overrideMaterial ) {
scene.overrideMaterial = null;
}
if ( debugMode & 2 ) {
if ( ! window.threejsOcclusionOverlayCanvas ) {
var overlayCanvas = document.createElement('CANVAS');
overlayCanvas.style.position = 'absolute';
overlayCanvas.style.top = '0';
overlayCanvas.style.left = '0';
overlayCanvas.style.bottom = '0';
overlayCanvas.style.right = '0';
overlayCanvas.style.width = '100%';
overlayCanvas.style.height = '100%';
container.appendChild(overlayCanvas);
window.threejsOcclusionOverlayCanvas = overlayCanvas;
}
}
else if ( window.threejsOcclusionOverlayCanvas ) {
window.threejsOcclusionOverlayCanvas.parentNode.removeChild(window.threejsOcclusionOverlayCanvas);
window.threejsOcclusionOverlayCanvas = null;
}
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
camera.position.x = Math.cos(mouseX * Math.PI) * 2000;
camera.position.y = mouseY * 1000;
camera.position.z = Math.sin(mouseX * Math.PI) * 2000;
camera.lookAt( scene.position );
renderer.render( scene, camera );
var occlusionStatsText = '';
// console.log(renderer.info);
for ( var stat in renderer.info.occlusion ) {
occlusionStatsText += stat + ": " + renderer.info.occlusion[ stat ] + "\n";
}
if ( occlusionStats.textContent !== occlusionStatsText ) {
occlusionStats.textContent = occlusionStatsText;
}
}
</script>
</body>
</html>
three.js
renderer
的occlusionCulling
属性在r58
版本有,最新版的该属性被移除了,移除原因我想也是我开头说的原因吧,有兴趣的同学可以深入研究一下。文章来源:https://www.toymoban.com/news/detail-637619.html
webgl实现
https://tsherif.github.io/webgl2examples/occlusion.html
这个是webgl的例子。文章来源地址https://www.toymoban.com/news/detail-637619.html
到了这里,关于【Three.js】遮挡剔除的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!