Hi everybody,
We are developing an App that contains multiple Reflectors (up to about 13).
As soon an we reach about 6 or 7 Reflectors the App gets very laggy and the OrbitControls are barely usable.
Is there some way to improve the performance of Reflectors?
For us it is more important that the Reflectors show the other 3D objects than the re-reflected image of the other Reflectors.
Can we reduce the recursion rate?
Can we avoid that Reflectors show other Reflectos at all?
Thanks for help
P.S. This modified sample app demonstrates our problem.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - mirror</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
<style>
body {
color: #444;
}
a {
color: #08f;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - mirror
</div>
<script type="module">
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './OrbitControls.js';
import { Reflector } from './Reflector.js';
// scene size
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
// camera
var VIEW_ANGLE = 45;
var ASPECT = WIDTH / HEIGHT;
var NEAR = 1;
var FAR = 500;
var camera, scene, renderer;
var cameraControls;
var sphereGroup, smallSphere;
init();
animate();
function init() {
var container = document.getElementById( 'container' );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( WIDTH, HEIGHT );
container.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
camera.position.set( 0, 75, 160 );
cameraControls = new OrbitControls( camera, renderer.domElement );
cameraControls.target.set( 0, 40, 0 );
cameraControls.maxDistance = 400;
cameraControls.minDistance = 10;
cameraControls.update();
//
var planeGeo = new THREE.PlaneBufferGeometry( 100, 100 );
// reflectors/mirrors
var geometry = new THREE.CylinderBufferGeometry( 0.1, 15 * Math.cos( Math.PI / 180 * 30 ), 0.1, 24, 1 );
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x444444 } );
var sphereCap = new THREE.Mesh( geometry, material );
sphereCap.position.y = - 15 * Math.sin( Math.PI / 180 * 30 ) - 0.05;
sphereCap.rotateX( - Math.PI );
var geometry = new THREE.SphereBufferGeometry( 15, 24, 24, Math.PI / 2, Math.PI * 2, 0, Math.PI / 180 * 120 );
var halfSphere = new THREE.Mesh( geometry, material );
halfSphere.add( sphereCap );
halfSphere.rotateX( - Math.PI / 180 * 135 );
halfSphere.rotateZ( - Math.PI / 180 * 20 );
halfSphere.position.y = 7.5 + 15 * Math.sin( Math.PI / 180 * 30 );
scene.add( halfSphere );
// walls
var planeTop = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
planeTop.position.y = 100;
planeTop.rotateX( Math.PI / 2 );
scene.add( planeTop );
var planeBottom = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
planeBottom.rotateX( - Math.PI / 2 );
scene.add( planeBottom );
// MIRRORS
var geometry = new THREE.PlaneBufferGeometry( 45, 100 );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.y = 50;
verticalMirror.position.z = - 50;
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = 50;
verticalMirror.position.y = 50;
verticalMirror.rotateY( - Math.PI / 2 );
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = -50;
verticalMirror.position.y = 50;
verticalMirror.rotateY(Math.PI / 2 );
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.y = 50;
verticalMirror.position.z = 50;
verticalMirror.rotateY(Math.PI);
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = 50 * 0.707;
verticalMirror.position.y = 50;
verticalMirror.position.z = 50 * -0.707;
verticalMirror.rotateY(Math.PI * -1 / 4);
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = 50 * -0.707;
verticalMirror.position.y = 50;
verticalMirror.position.z = 50 * 0.707;
verticalMirror.rotateY(Math.PI * 3 / 4);
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = 50 * 0.707;
verticalMirror.position.y = 50;
verticalMirror.position.z = 50 * 0.707;
verticalMirror.rotateY(Math.PI * -3 / 4);
scene.add( verticalMirror );
var verticalMirror = new Reflector( geometry, {
clipBias: 0.003,
textureWidth: WIDTH * window.devicePixelRatio,
textureHeight: HEIGHT * window.devicePixelRatio,
color: 0x889999
} );
verticalMirror.position.x = 50 * -0.707;
verticalMirror.position.y = 50;
verticalMirror.position.z = 50 * -0.707;
verticalMirror.rotateY(Math.PI * 1 / 4);
scene.add( verticalMirror );
// lights
var mainLight = new THREE.PointLight( 0xcccccc, 1.5, 250 );
mainLight.position.y = 60;
scene.add( mainLight );
var greenLight = new THREE.PointLight( 0x00ff00, 0.25, 1000 );
greenLight.position.set( 550, 50, 0 );
scene.add( greenLight );
var redLight = new THREE.PointLight( 0xff0000, 0.25, 1000 );
redLight.position.set( - 550, 50, 0 );
scene.add( redLight );
var blueLight = new THREE.PointLight( 0x7f7fff, 0.25, 1000 );
blueLight.position.set( 0, 50, 550 );
scene.add( blueLight );
}
function animate() {
requestAnimationFrame( animate );
var timer = Date.now() * 0.01;
renderer.render( scene, camera );
}
</script>
</body>
</html>