icebobofly
icebobofly

Reputation: 1

How to avoid transparency overlap using threejs

I am using threejs to build a map application, and I need to make all building models translucent, but in this case, the transparent buildings will overlap, resulting in a confusing display effect, as shown in the following figure

Overlapping renderings

The effect I hope to achieve is similar to the example on mapboxgl, the nearby buildings can directly block the buildings behind, which is much more refreshing

Expected renderings

How can this be done?

scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
scene.background = new THREE.Color( 0x4186D1 );
// scene.fog = new THREE.FogExp2( 0x4186D1, 0.002 );
scene.fog = new THREE.Fog( 0x4186D1, 800, 1800 );

renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 400, 200, 0 );

// controls

controls = new MapControls( camera, renderer.domElement );

controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)

controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;

controls.screenSpacePanning = false;

controls.minDistance = 100;
controls.maxDistance = 500;

controls.maxPolarAngle = Math.PI / 2;

// world

const geometry = new THREE.BoxGeometry( 1, 1, 1 );
geometry.translate( 0, 0.5, 0 );
const material = new THREE.MeshPhongMaterial( { color: 0xffffff, transparent: true, opacity: 0.7, flatShading: true } );

for ( let i = 0; i < 500; i ++ ) {

    const mesh = new THREE.Mesh( geometry, material );
    mesh.position.x = Math.random() * 1600 - 800;
    mesh.position.y = 0;
    mesh.position.z = Math.random() * 1600 - 800;
    mesh.scale.x = 20;
    mesh.scale.y = Math.random() * 80 + 10;
    mesh.scale.z = 20;
    mesh.updateMatrix();
    mesh.matrixAutoUpdate = false;
    scene.add( mesh );

}

// lights

const dirLight1 = new THREE.DirectionalLight( 0xffffff );
dirLight1.position.set( 1, 1, 1 );
scene.add( dirLight1 );

const dirLight2 = new THREE.DirectionalLight( 0x002288 );
dirLight2.position.set( - 1, - 1, - 1 );
scene.add( dirLight2 );

const ambientLight = new THREE.AmbientLight( 0x222222 );
scene.add( ambientLight );

//

window.addEventListener( 'resize', onWindowResize );


const gui = new GUI();
gui.add( controls, 'screenSpacePanning' );

Upvotes: 0

Views: 649

Answers (0)

Related Questions