Reputation: 891
I have two overlapping semitransparent boxes and I'd expect to see both of them independent of the viewing angle. The first image shows a rendering from aside and the small box is visible within the bigger box. The second image shows the same scene but form another viewing angle. As you can see, the smaller box is visible but the part which is with the bigger box is invisible. What am I missing?
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Upvotes: 0
Views: 268
Reputation: 4495
Transparent objects in WebGL are sometimes rather problematic. It's all about the rendering order: If the small cube is rendered after the large cube, how should the rendering behave? This question has some information you might find useful.
In your particular case (though not necessarily always), one solution could be to disable renderer object sorting:
renderer.sortObjects = false;
and(!) make sure you add your objects in the correct order, i.e. the small cube first and the large one second. Here is an updated version of your snippet:
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.sortObjects = false;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Upvotes: 1