Problems with setting child's material

I’m trying to match the reference. I have a strawberry consisting of the top green part, the red body, and the part that is covered in the chocolate (top layer) The single .obj provided by the designer doesn’t have names in it. So I can’t distinguish the parts of the strawberry. I got so close to matching the chocolate layer, but the problem is that the whole strawberry becomes chocolatey. I can’t get my head around how to make it right. Any advice?

The desired output has been provided by the designer, .obj and .mtl files created and exported from Blender:

Actual output:

Here is how I’m doing it:

// Lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
directionalLight1.position.set(5, 5, 5);
directionalLight1.castShadow = true;
scene.add(directionalLight1);

const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight2.position.set(-5, 5, 5);
scene.add(directionalLight2);

// Additional light to highlight the chocolate layer
const spotLight = new THREE.SpotLight(0xffffff, 1.0);
spotLight.position.set(0, 10, 0);
spotLight.castShadow = true;
spotLight.angle = Math.PI / 4;
scene.add(spotLight);

// Fill light to illuminate the chocolate layer better
const fillLight = new THREE.PointLight(0xffffff, 1.0);
fillLight.position.set(0, 3, 5);
scene.add(fillLight);

// Renderer
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  antialias: true,
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

// Custom materials
const strawberryMaterial = new THREE.MeshPhongMaterial({
  color: 0xff0000,
  specular: 0x550000,
  shininess: 30,
});

const leafMaterial = new THREE.MeshPhongMaterial({
  color: 0x00ff00,
  specular: 0x005500,
  shininess: 20,
});

const chocolateMaterial = new THREE.MeshPhongMaterial({
  color: 0x8B4513,
  specular: 0x222222,
  shininess: 50,
});

// Load model
new MTLLoader()
  .setPath("./assets/")
  .load("untitled.mtl", (materials) => {
    materials.preload();

    new OBJLoader()
      .setMaterials(materials)
      .setPath("./assets/")
      .load(
        "untitled.obj",
        (object) => {
          object.position.set(0, 0, 0);
          object.traverse((child) => {
            if (child.isMesh) {
              child.castShadow = true;
              child.receiveShadow = true;

              // Log child name to identify its type
              console.log(child.name);

              child.material = chocolateMaterial;

              // Apply materials based on index or identify manually
              // if (child.name.includes("Leaf") || child.name.includes("leaf")) {
              //   child.material = leafMaterial;
              // } else if (child.name.includes("Strawberry") || child.name.includes("strawberry")) {
              //   child.material = strawberryMaterial;
              // } else {
              //   child.material = chocolateMaterial;
              // }
            }
          });
          scene.add(object);
        },
        (xhr) => {
          console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
        },
        (error) => {
          console.log("An error happened", error);
        }
      );
  });

don’t do that in code, load the obj in blender, fix the colors and textures there, bake shadows and ao. then export as a compressed glb and use it.

i see only disadvantages otherwise, file’s way too big, ugly traversal code, it won’t come close to the blender visuals.

Thanks for getting back to me. I don’t have any experience at all with Blender or any 3d software at all, to be honest. Can you please elaborate on what needs to be done so I can pass this feedback on to the designer?

tell them to give you a GLB that is ready to be consumed by the web: low poly and baked AO. AO short for ambient occlusion is what creates these realistic shadowy areas. they can give you the envmap hdri as well which is what creates the light and reflections.

your part:

  • load glb
  • load envmap
  • it will look exactly like the blender original ootb

A very detailed response, much appreciated indeed!