如何在材质上使用透明PNG显示背景颜色?

9
我正在使用THREE.js制作一个箱子构建器,基本上我想能够改变盒子的高度/宽度/长度,围绕其旋转,并且还可以更改盒子的背景颜色。
到目前为止,这就是它的样子:http://design365hosting.co.uk/casebuilder3D/ 尺寸更改和拖动盒子都有效,现在我正在处理背景颜色更改。
我希望通过使用透明PNG作为盒子的面,设置背景颜色,使得该背景颜色通过透明PNG显示出来。
这是我目前的做法:
var texture = THREE.ImageUtils.loadTexture("images/crate.png");
materials.push(new THREE.MeshBasicMaterial({color:0xFF0000, map: texture}));

如您所见,我将材料设为红色背景并覆盖透明PNG,但问题是,three.js似乎忽略了背景颜色,只显示透明PNG,意味着没有颜色显示出来。
预期结果应该是一个带有叠加PNG的红色框。
希望这样说有意义,有人能帮忙吗?
1个回答

18

您正在尝试将透明贴图应用为贴花。

three.js内置材质不支持您要做的操作。 如果PNG是部分透明的,则材质将部分透明。

您希望材质保持不透明,并将纹理应用为贴花。

您可以通过修改材质的着色器来实现。例如,

var material = new THREE.MeshPhongMaterial( {
    color: 0x0080ff,
    map: texture
} );

material.onBeforeCompile = function ( shader ) {

    const custom_map_fragment = THREE.ShaderChunk.map_fragment.replace(

        `diffuseColor *= sampledDiffuseColor;`,

        `diffuseColor = vec4( mix( diffuse, sampledDiffuseColor.rgb, sampledDiffuseColor.a ), opacity );`

    );

    shader.fragmentShader = shader.fragmentShader.replace( '#include <map_fragment>', custom_map_fragment );

};

three.js r.147


着色器并不会使材质“透过显示”,它只是用uniforms.color设置的红色填充alpha背景(应该是透明的)。这可以更容易地通过使用具有填充背景而不是透明背景的简单png来实现。此外,如果您的目标是拥有一个透明的平面(或物体),以便它不会遮挡场景中后面的任何东西,那么这种方法行不通。我找到解决方案后会更新此评论。 - Pablo K
1
@PabloKvitca 这个答案是针对所提出的问题编写的,而不是为了适应您的用例而编写的。如果您想针对自己的用例发布答案,可以创建一个新的问题并自己回答。 - WestLangley
据我理解,这是相同的用例,他想通过纹理展示。无论如何,我认为提出一个新问题是一个更好的主意。我会继续做到这一点。 - Pablo K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接