Three.js: Mesh disappears when enclosed within another mesh

I've been struggling for hours to understand why the text inside the cube is not visible, and I can't seem to figure out what's causing the issue.

There are two meshes, one nested inside the other, but it appears invisible.

If I comment out the line adding the cube mesh to my group, the text suddenly becomes visible (line 34). I am able to see the text if I remove the "transparent: true" from its material, but a background shows up instead (line 52).

The text is applied as a canvas texture, which seemed like the simplest way to dynamically add 2D text.

All I want is to insert some white text inside my cube without any background color showing through.

I came across this question, but it doesn't seem to be directly related to my current problem: THREE.JS: Seeing geometry when inside mesh

var renderer, scene, camera, cubeGroup;
var rotationX = 0;
var rotationY = 0;
var percentX, percentY;
var container = document.getElementById('container');

init();
animate();

function init(){
    renderer = new THREE.WebGLRenderer({alpha: true});
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor( 0x000000, 1);
    document.getElementById('container').appendChild(renderer.domElement);

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.set(0, 0, 1000);
    scene.add(camera);
    
    // group
    cubeGroup = new THREE.Group();
    
    // cube
    var geometry = new THREE.BoxGeometry(200, 200, 200);
    var material = new THREE.MeshPhongMaterial({ 
      color: 0x11111f, 
      side: THREE.DoubleSide, 
      opacity: .5,
      transparent: true 
    });
    var mesh = new THREE.Mesh(geometry, material);
    cubeGroup.add(mesh); // Comment this and the text appears with transparency
    
    var ambientLight = new THREE.AmbientLight(0x999999, 0.8);
    scene.add(ambientLight);
    
    // text
    var bitmap = document.createElement('canvas');
    var g = bitmap.getContext('2d');
    bitmap.width = 256;
    bitmap.height = 256;
    g.font = '80px Arial';
    g.fillStyle = 'white';
    g.fillText('text', 20, 80);
        
    var geometry = new THREE.PlaneGeometry(180, 180);
    var texture = new THREE.CanvasTexture(bitmap);
    var material = new THREE.MeshStandardMaterial({
        map: texture,
        transparent: true // Comment this and the text appears - but with background
    });
    
    var mesh2 = new THREE.Mesh(geometry, material);    
    cubeGroup.add(mesh2);
    
    // add group to scene
    scene.add(cubeGroup);
  
    window.addEventListener('resize', onWindowResize, false);
}


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 animate(now){
    requestAnimationFrame(animate);
  
    cubeGroup.rotation.y += (rotationX - cubeGroup.rotation.y) * 0.05;
    cubeGroup.rotation.x += (rotationY - cubeGroup.rotation.x) * 0.05;
        
    renderer.render(scene, camera);    
}

function findViewCoords(mouseEvent)
{
  var xpos;
  var ypos;
  var w = window.innerWidth;
  var h = window.innerHeight;
  var centerX = w/2;
  var centerY = h/2;

  if (mouseEvent)
  {
    xpos = mouseEvent.pageX - document.body.scrollLeft;
    ypos = mouseEvent.pageY - document.body.scrollTop;
  }
  else
  {
    xpos = window.event.x + 2;
    ypos = window.event.y + 2;
  }
  
  var diffX = xpos - centerX;
  var diffY = ypos - centerY;
  percentX = diffX / centerX;
  percentY = diffY / centerY;
 
  rotationX = percentX/2;
  rotationY = percentY/2; 
}

container.addEventListener("mousemove", findViewCoords);
body {
    margin: 0;
    padding: 0;
    overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.js"></script>

<div id="container"></div>

Answer №1

The reason behind this phenomenon is the two-phase rendering process in three.js.

Initially, solid objects are rendered followed by transparent elements.

The transparent objects are arranged based on their distance from the camera.

By setting .transparent = true; for your text, you ensure that it is rendered during the second phase, allowing it to appear on top of other geometries.

To dive deeper into this topic, explore the insightful answer provided by the remarkable West Langley:

Transparent objects in Threejs

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Learn the art of combining an ajax request with a captivating background animation at the same time

I'm currently working with the following code snippet: $('#contentSites').fadeOut(200, function() { // Animation complete $.get("my_account_content.php?q=" + content, function(data){ $("div#contentSit ...

Create an index.html file using webpack to utilize it with the development server

Using webpack to run my Three.js application, I have the following configuration in the webpack.config file: module.exports = { entry: `${__dirname}/src/tut15.js`, output: { path: __dirname + '/dist', filename: 'index_bundle.js&a ...

Adding a placeholder to a MUI Select component with different value prop and MenuItem options: a step-by-step guide

Is there a way to include a placeholder (-- Select --) in the MUI Select component below? const [country, setCountry] = useState("") <FormControl fullWidth error={!country}> <Select displayEmpty renderValue={selected => sel ...

Using Jquery $.ajax may lead to temporary freezing of the Browser

I have a $ajax function that fetches multiple JSON objects from a URL and converts them into divs. There are around 50 objects, and I am using setInterval to call the $ajax function every 10 seconds for updates on each of the created divs. However, I' ...

Expanding Material Ui menu to occupy the entire width of the page

I'm encountering an issue with a menu I created where I can't seem to adjust its height and width properly. It seems to be taking up the full width of the page. import React, { Component } from "react"; import Menu from "@material-ui/core/Menu"; ...

Having trouble determining the total amount in my online shopping cart

I am facing an issue with the shopping cart I created, which consists of two components (Productlist and Cart List). When I click on the 'add to cart' button in the Product List, it successfully moves into the service file and then to the Cart Li ...

Utilizing Reactjs to transform a locally stored CSV file into JSON

Currently, I am attempting to convert a .csv file into a JSON object within Reactjs. To do this, I first add the file that needs conversion to the project structure under a folder named Data. Following this, I came across an npm package at https://www.npmj ...

When trying to execute cordova, meteor.js encounters an issue locating the is-property module

Error image After encountering the error above, I decided to try accessing the program on a different computer - and surprisingly, it worked flawlessly. On my main machine, I have meteor, npm, is-property, and node all installed and functioning correctly. ...

Tips on organizing a two-dimensional array based on the values in a specific column?

I could use some assistance with sorting a 2D array in JavaScript. The array will be structured like this: [12, AAA] [58, BBB] [28, CCC] [18, DDD] After sorting, it should appear like this: [12, AAA] [18, DDD] [28, CCC] [58, BBB] In essence, I need to ...

Replace the plus signs in a string with spaces using the JSON.stringify method

When utilizing AJAX, I am sending the string someString to a PHP handler. xmlHttp.open("POST", url, true); var someString = 'Foo+Bar'; var params = 'operation='+operation+'&json='+JSON.stringify(someString); xmlHttp.send( ...

Making alterations to the content of a division using getElementById().innerHTML yields no difference

Recently, I've been working on a JS project inspired by a short story from my high school days. The story featured robot crabs living on a small island, and I wanted to create a simulator where players could set the initial parameters and watch as the ...

Create dynamic and interactive content by embedding text within SVG shapes using the powerful D

How can I write text into an SVG shape created with d3.js and limit it to stay inside the shape similar to this example http://bl.ocks.org/mbostock/4063582? I attempted to use a clipPath following the example provided. However, when inspecting with firebu ...

Transferring information from socket.io to vue.js

I am currently facing an issue with passing socket.io data to a Vue.js element. Despite going through the Vue documentation multiple times, I have not been able to find a solution. The data is being sent to the client via socket.io and successfully logged ...

Using jQuery and PHP to submit a form

I'm attempting to trigger a form submission when a button on another form is clicked. The goal is to update the form without losing any previously entered data. It's important to note that these forms are not exactly the same, but for the sake o ...

Angular2 does not load Js twice

I specified the path to my JS file in angular.cli. It loaded successfully during the initialization of the Angular app, but when navigating back to the component, it failed to load. Any suggestions on how to fix this issue would be greatly appreciated. Th ...

Highlight or unhighlight text using Javascript

Currently, I am facing a challenge in highlighting specific words on an HTML page. Although I have succeeded in highlighting the desired element, I am struggling with unhighlighting the previous word when a new search is conducted. Despite my attempts to i ...

What is the best way to allocate values within a for loop?

I am in the process of designing an interface for individuals who have no background in programming. My goal is to allow them to input certain details, and then be able to simply copy and paste the code to make everything function seamlessly. Here is a sa ...

How can I refresh the content on my Vue.js website automatically when a webhook is triggered

I currently have a Vue 3 website that displays a list fetched from a REST-API using the fetch method. Occasionally, this list is updated in the original database, and I want my Vue component to reflect those changes. The exciting part is that a webhook is ...

Why does console.log in JavaScript exhibit different behaviors as evidenced by the code?

Exploring the behavior of console.log(obj) compared to console.log("obj"+"\n"+obj) in the code snippet below reveals two distinct output outcomes. const obj = new Object() obj.first = 'John' obj.last = 'Doe' obj.alive = true ob ...

Troubleshoot the issue of the service function not being triggered

Seeking help with my Angular project as I am facing an issue with resolve and $resource. Despite spending a whole day on it, I couldn't find a solution. When using resolve to fetch data with $resource and ui-router, the service method never gets calle ...