Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js png texture - alpha renders as white instead as transparent

Tags:

three.js

webgl

I'm creating a cube and I apply 6 different textures to each of it's faces. Each texture is a .png file and contains transparent parts. I'm also applying a color to the cube - I want to see that color trough png transparency.

Problem: Transparency renders as white color so I cannot see the base color of the cube (which renders ok if I remove the png texture)

How can I make the png transparency work? I tried playing with some material settings but none make it transparent.

Code for creating the cube and 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); 

EDIT:

Picture below shows the problem - with senthanal solution the left texture now renders ok - it is a png image without transparency - I set the transparency in code with

materialArray.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture('img/s2.png'), transparent: true, opacity: 0.9, color: 0xFF0000 })); 

The right texture is also a png image - only that it has a transparent area (all that renders white should be pure red since it is transparent and should take the color from the cube?). How can I make that white part transparent?

enter image description here

like image 753
easwee Avatar asked Jul 05 '13 10:07

easwee


People also ask

How do you make a mesh transparent in 3 JS?

Mesh(geometry2, material2); // Definition 1 var geometry1 = new THREE. SphereGeometry(1.0, 32, 24); var material1 = new THREE. MeshLambertMaterial({color: 0xff0000, transparent: true, opacity: 0.5}); var sphere1 = new THREE. Mesh(geometry1, material1); scene.

Does PNG support semi transparency?

The GIF and PNG formats also both support transparency. If you need any level of transparency in your image, you must use either a GIF or a PNG. GIF images (and also PNG) support 1-color transparency.


2 Answers

the opacity attribute of material does the trick for you. Follows, 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 );     

http://threejs.org/docs/#Reference/Materials/Material The key is to set transparent attribute true and set opacity to 0.5(for example). Add the second the cube which fits inside exactly with no transparency, idea from @WestLangley ( 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 ); 
like image 142
senthanal Avatar answered Sep 18 '22 16:09

senthanal


for those looking for a simple transparent png import helper:

import { MeshBasicMaterial, TextureLoader } from 'three'  export const importTexture = async(url, material) => {     const loader = new TextureLoader()     const texture = await loader.loadAsync(url)     material.map = texture     material.transparent = true     material.needsUpdate = true     return texture }   //usage const geo = new PlaneGeometry(1, 1) const mat = new MeshBasicMaterial() const mesh = new Mesh(geo, mat) scene.add(mesh) //this is asynchronous importTexture('path/to/texture.png', mat) 
like image 29
Peter Hayman Avatar answered Sep 19 '22 16:09

Peter Hayman