Issues with rendering alpha transparency correctly in Three.js png textures can be frustrating. Sometimes, the alpha

For my project, I am working on creating a cube and applying 6 different textures to each of its faces. These textures are .png files with transparent parts. Additionally, I want to apply a color to the cube and have that color show through the transparent areas of the textures.

However, I have encountered an issue where the transparency renders as white, obscuring the base color of the cube that otherwise renders correctly without the textures.

I have experimented with various material settings but have not been successful in making the png transparency work as intended.

Below is the code I am using to create the cube and assign materials:

var geometry = new THREE.CubeGeometry(150, 200, 150, 2, 2, 2);
var materials = [];

// create textures array for all cube sides
for (var i = 1; i < 7; i++) {
   var img = new Image();
   img.src = 'img/s' + i + '.png';
   var tex = new THREE.Texture(img);
   img.tex = tex;

   img.onload = function () {
      this.tex.needsUpdate = true;
   };

   var mat = new THREE.MeshBasicMaterial({color: 0x00ff00, map: tex, transparent: true, overdraw: true });
   materials.push(mat);
}
cube = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add(cube);

In the image below, the solution by senthanal successfully renders the left texture, which is a png image without transparency. However, the right texture contains transparency that shows up as white instead of taking on the color of the cube. How can I make the white part transparent and display the red color from the cube?

Answer №1

Utilizing the opacity attribute of a material can help achieve the desired effect. Below is an example code snippet:

var materialArray = [];

materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/xpos.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/xneg.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/ypos.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/yneg.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/zpos.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'images/zneg.png' ), transparent: true, opacity: 0.5, color: 0xFF0000 }));

var MovingCubeMat = new THREE.MeshFaceMaterial(materialArray);
var MovingCubeGeom = new THREE.CubeGeometry( 50, 50, 50, 1, 1, 1, materialArray );

MovingCube = new THREE.Mesh( MovingCubeGeom, MovingCubeMat );
MovingCube.position.set(0, 25.1, 0);

scene.add( MovingCube );    

The key is to set transparent attribute true and set opacity to 0.5 (for example). To add another cube inside without transparency, refer to @WestLangley's idea (Three.js canvas render and transparency)

backCube = new THREE.Mesh( MovingCubeGeom, new THREE.MeshBasicMaterial( { color: 0xFF0000 }) );
backCube.position.set(0, 25.1, 0);
backCube.scale.set( 0.99, 0.99, 0.99 );
scene.add( backCube );

Answer №2

If you're in need of a straightforward solution for importing transparent PNG files, consider using this helper function:

import { MeshBasicMaterial, TextureLoader } from 'three'

export const loadTexture = async(url, material) => {
    const loader = new TextureLoader()
    const texture = await loader.loadAsync(url)
    material.map = texture
    material.transparent = true
    material.needsUpdate = true
    return texture
}


// example usage
const geometry = new PlaneGeometry(1, 1)
const material = new MeshBasicMaterial()
const mesh = new Mesh(geometry, material)
scene.add(mesh)
// execute asynchronously
loadTexture('path/to/texture.png', material)

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

Updating state in Vue by utilizing an array of item values

Hello everyone In a simple application, I am attempting to visualize the insertion sort algorithm using Vue. I have successfully written a function that sorts a list of items and returns an array showing each step of the sorting process. The final array i ...

Activate the Flexslider when it comes into view

Currently using flexslider, I am attempting to create a smooth transition from the second slide back to the first as soon as the slider is in view. My initial idea was to implement if (scroll >= 500px && scroll < 600px) however, I am uncerta ...

Trouble with executing asynchronous AJAX request using when() and then() functions

Here is the code that I am currently using: function accessControl(userId) { return $.ajax({ url: "userwidgets", type: "get", dataType: 'json', data: { userid: userId } }); }; var user ...

Trouble with getTime() function functionality in Chrome browser

My JavaScript code is functioning properly in IE and Firefox. Take a look: var dt = new Date("17/05/2012 05:22:02").getTime(); However, when I try to run it in Chrome, the value of dt turns out to be NaN. I've been troubleshooting but can't see ...

Angular material table featuring custom row design

My team is working with a large table that is sorted by date, and we are looking to add some guidance rows to help users navigate through the data more easily. The desired structure of the table is as follows: |_Header1_|_Header2_| | 25/11/2018 | ...

Tips for preventing the use of eval when invoking various functions

Here's a snippet of code I've been using that involves the use of eval. I opted for this approach as it seemed like the most straightforward way to trigger various factory functions, each responsible for different web service calls. I'm awa ...

Mastering the Art of Page Scrolling with d3

I would like to implement a scrolling effect for my d3 that allows the entire page to scroll while panning, similar to the effect on challonge (http://challonge.com/tournaments/bracket_generator?ref=OQS06q7I5u). However, I only want the scrolling to occur ...

Using properties to generate a header component in TypeScript

I am currently exploring TypeScript and incorporating it into a project for the first time. I'm encountering a challenge as I am not sure what to call this concept, making it difficult to search for solutions. If someone can provide me with the term, ...

An error occurs when using e.slice function

I am facing an issue with my kendoDropDownList that uses kendo UI and jQuery. I cannot figure out why this error is occurring. $("#drpState").kendoDropDownList({ optionLabel: "States...", delay: 10, ...

Having trouble with React's conditional rendering not working as expected?

I am currently working on updating the contents of my Navbar and Router by using useContext and conditional rendering techniques. Here is a snippet from my App.js: import "./App.css"; import axios from "axios"; import { AuthContextProv ...

React-router causing issues with Redux integration

Currently, I'm utilizing the following libraries: react v16.2.0, react-redux v5.0.7, react-router-dom v4.2.2, redux v3.7.2 The main goal is to update some properties within the Auth component and have these changes reflected when the user visits the ...

Is it possible for SqlCommand.ExecuteReader to automatically open the database connection?

Unusual behavior is happening on my website. I have a WCF Data service that provides JSON data to populate a jqGrid using javascript/ajax calls. In addition, there is server-side code that also accesses the same WCF service to retrieve data. Within my WC ...

Struggling to concatenate array dynamically in Vue using ajax request

I am working on a Vue instance that fetches objects from a REST endpoint and showcases them on a web page. Most parts of the functionality work smoothly like filtering, however, there is an issue when attempting to add new objects by requesting a new "page ...

Can you explain the key distinction between the backtick (`) and the ampersand-hash-39

I am completely new to TypeScript, JavaScript, and Angular. As I follow some tutorials, I often encounter code snippets like the one below: class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${th ...

The jQuery change event does not fire once the DIV has been rendered, while working with CakePHP

Whenever a room_id is chosen from the drop-down menu, I utilize the JS helper to automatically fill in the security_deposit and room_rate input fields. However, there seems to be an issue where selecting a room_id causes the room_rate_update jQuery change ...

Redirect in ExpressJS after a DELETE request

After extensive searching, I am still unable to figure out how to handle redirection after a DELETE request. Below is the code snippet I am currently using WITHOUT THE REDIRECT: exports.remove = function(req, res) { var postId = req.params.id; Post.re ...

How can I turn off popover when I am moving an event?

Is there a way to hide the popover element when dragging an event in fullcalendar, and then show the popover again after the dragging is stopped? Here is the code I am currently using: eventRender: function(event, elementos, resource, view) { var ...

angular2 and ionic2 encounter issues when handling requests with observable and promises

I am attempting to trigger an action once a promise request has been resolved, but I'm having trouble figuring out how to achieve this. After doing some research, I learned that Ionic2 storage.get() returns a promise, and I would like to make an HTTP ...

Error message: Act must be used when rendering components with React Testing Library

I am facing difficulty while using react-testing-library to test a toggle component. Upon clicking an icon (which is wrapped in a button component), I expect the text to switch from 'verified' to 'unverified'. Additionally, a function ...

List the attributes that have different values

One of the functions I currently have incorporates lodash to compare two objects and determine if they are identical. private checkForChanges(): boolean { if (_.isEqual(this.definitionDetails, this.originalDetails) === true) { return false; ...