9

I'm making a case builder using THREE.js, the basics are i want to be able to change the height/width/length of a box, rotate it around, and also change the background color of the box.

This is it so far: http://design365hosting.co.uk/casebuilder3D/

The dimension changing works, as does the dragging of the box, now i'm working with the background color change.

The way i want this to work is by using transparent PNGs as the faces of the box, and setting background colors so that this background colour shows through the transparent PNG.

This is how I'm currently doing it:

var texture = THREE.ImageUtils.loadTexture("images/crate.png");
materials.push(new THREE.MeshBasicMaterial({color:0xFF0000, map: texture}));

as you can see I set the material to have a background colour of red and overlay the transparent PNG, problem is, three.js seems to ignore the background colour and just show the transparent PNG, meaning no colour shows through.

The expected result should be a red box with the overlayed PNG.

Hope that made sense, can anyone help?

Edric
  • 24,639
  • 13
  • 81
  • 91
James
  • 1,138
  • 9
  • 13

1 Answers1

18

You are trying to apply your transparent texture as a decal.

The three.js built-in materials do not support what you are trying to do. If the PNG is partially transparent, then the material will be partially transparent.

You would like the material to remain opaque, and the texture to be applied as a decal.

You can do this by modifying the material's shader. For example,

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

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • The shader does not make the material "show through", it merely fills the alpha background (which should be transparent) with a red color (the one set on the uniforms.color). This can more easily be achieved using a simply png with a filled background instead of a transparent one. Furthermore, if your goal is to have a transparent plane (or object), so it doesn't occlude whatever is behind it on the scene, this does not work. I will update this comment when I find a solution to this case. – Pablo K Jun 21 '18 at 19:49
  • 1
    @PabloKvitca This answer was written in response to the question that was asked; it was not written to accommodate your use case. If you want to post an answer to your use case, you can create an new a question and answer it yourself. – WestLangley Jun 22 '18 at 03:25
  • as I understood the question it was the same use case, he wanted a show through texture. Anyway, I see that making a new question is a better idea. I'll go ahead and do that. – Pablo K Jun 25 '18 at 18:57