Three.js png 纹理 - alpha 渲染为白色而不是透明

问题描述 投票:0回答:2

我正在创建一个立方体,并为它的每个面应用 6 种不同的纹理。每个纹理都是一个 .png 文件并包含透明部分。我还在立方体上应用了颜色 - 我想通过 png 透明度看到该颜色。

问题:透明度渲染为白色,因此我看不到立方体的基色(如果删除 png 纹理,则渲染正常)

如何使 png 透明度起作用?我尝试使用一些材质设置,但没有一个使其透明。

创建立方体和材质的代码:

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);

下图显示了问题 - 使用senthanal解决方案,左侧纹理现在渲染正常 - 这是一个没有透明度的png图像 - 我在代码中设置了透明度

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

正确的纹理也是一个 png 图像 - 只是它有一个透明区域(所有渲染白色的都应该是纯红色,因为它是透明的并且应该从立方体中获取颜色?)。我怎样才能使白色部分透明?

enter image description here

javascript three.js webgl
2个回答
42
投票

材质的不透明度属性可以帮到你。下面是示例代码片段:

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://thirdjs.org/docs/#Reference/Materials/Material 关键是设置透明属性为true,并将不透明度设置为0.5(例如)。 添加第二个立方体,它完全适合内部,没有透明度,想法来自@WestLangley(Three.js画布渲染和透明度

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 );

6
投票

对于那些寻找简单的透明 png 导入助手的人:

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)
© www.soinside.com 2019 - 2024. All rights reserved.