Skip to content

Materials are rendered wrong when using Material Array #675

@PratikHadawale-tech

Description

@PratikHadawale-tech

Describe the bug

Link to CodeSandBox is included later in here

For example: Consider a BoxGeometry with 6 groups and a material array with 6 materials, one material for each group and one group for each face of the BoxGeometry

When we pass a "material array" to the "Mesh" function, it leads to the following bugs:

  1. The first material of the material array is applied to the entire Mesh, basically ignoring the rest of the material array
  2. The colors of other Meshes gets affected ( if we have a mesh in scene using material array )

Both these bugs may or may not appear at the same time.

These bugs appear even if we construct proper "groups" for the geometry and if we setScene() after creating the Mesh:

  1. When we clear the groups and then construct our own groups
  2. We just update the material index of the groups

Note: The Mesh looks perfectly fine and utilizes the material array properly, resulting in faces using all materials from material array, when I don't use pathtracing or When samples count is 0

Note: If I were to create a cube with 6 different materials in blender, export as GLB and import in three.js. Then start Pathtracing, it works perfectly.

EDIT: Looks like, blender exports a cube as planes. Could it be the case that three-gpu-pathtracer doesn't work with geometry groups and material arrays?

Expected behavior

When we use Material Array and proper groups for geometry, instead of leading to the bugs described above. The pathtracing render should display

  1. A scene where each face of the box geometry has a material assigned from the material array according to the groups, and not just the first material from the material array
  2. It shouldn't affect other meshes present in the scene

Screenshots and Repro Model

In the code below, refer to the following functions: setup(), setupDummyMesh(), setupPathTracer()

import {
    BoxGeometry,
    Mesh,
    MeshPhysicalMaterial,
    PerspectiveCamera,
    RectAreaLight,
    Scene,
    WebGLRenderer,
    EquirectangularReflectionMapping
} from 'three';

import { WebGLPathTracer } from 'three-gpu-pathtracer';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { RGBELoader } from 'three/examples/jsm/Addons.js';

class Measurement {
    constructor() {
        this._scene = null;
        this._camera = null;
        this._renderer = null;

        this._orbitControls = null;

        this._pathTracer = null;
    }

    async setupEnvironmentTexture(hdrName) {
        const envTexture = await new RGBELoader().loadAsync('/hdr/' + hdrName + '.hdr')
        envTexture.mapping = EquirectangularReflectionMapping
        this._scene.backgroundRotation.x = 1.5
        this._scene.environment = envTexture;
        return envTexture
    }

    setupPathTracer() {
        this._pathTracer = new WebGLPathTracer(this._renderer)
        this._pathTracer.filterGlossyFactor = 1
        this._pathTracer.physicallyCorrectLights = true
        this._pathTracer.transmissiveBounces = 10
        this._pathTracer.multipleImportanceSampling = true

        this._orbitControls.addEventListener('change', () => {
            this._pathTracer.updateCamera()
        })
    }

    setupLights() {
        const rectLight = new RectAreaLight();
        rectLight.position.set(5, 5, 0);
        rectLight.lookAt(0, 0, 0);

        this._scene.add(rectLight);

        const rectLight1 = new RectAreaLight();
        rectLight1.position.set(-5, 5, 0);
        rectLight1.lookAt(0, 0, 0);

        this._scene.add(rectLight1);

        const rectLight2 = new RectAreaLight();
        rectLight2.position.set(-5, -5, 0);
        rectLight2.lookAt(0, 0, 0);

        this._scene.add(rectLight2);
    }

    setupOrbitControls() {
        this._orbitControls = new OrbitControls(this._camera, this._renderer.domElement);
        this._orbitControls.enableDamping = true;
        this._orbitControls.dampingFactor = 0.3;
    }

    setupDummyMesh() {
        const geometry = new BoxGeometry();

        const materials = [
            new MeshPhysicalMaterial({ color: 0x0a5d00 }),
            new MeshPhysicalMaterial({ color: 0x1fc600 }),
            new MeshPhysicalMaterial({ color: 0xc80000 }),
            new MeshPhysicalMaterial({ color: 0x7b0000 }),
            new MeshPhysicalMaterial({ color: 0x000055 }),
            new MeshPhysicalMaterial({ color: 0x0000C7 })
        ]

        geometry.clearGroups()
        geometry.addGroup(0, 6, 0)
        geometry.addGroup(6, 6, 1)
        geometry.addGroup(12, 6, 4)
        geometry.addGroup(18, 6, 5)
        geometry.addGroup(24, 6, 2)
        geometry.addGroup(30, 6, 3)

        const mesh = new Mesh( geometry, materials )



        this._scene.add(mesh)
        this.setScene()
        
        // this._pathTracer.updateMaterials();
    }

    setScene(){
        this._pathTracer.setScene(this._scene, this._camera )
    }

    setup() {
        this._scene = new Scene();

        this._camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this._camera.position.z = 5;
        this._camera.position.x = 5;
        this._camera.position.y = 5;

        this._renderer = new WebGLRenderer();
        this._renderer.setSize(window.innerWidth, window.innerHeight);
        this._renderer.setAnimationLoop(this.animate.bind(this));
        document.body.appendChild(this._renderer.domElement);

        this.setupOrbitControls()
        this.setupPathTracer();
        this.setupLights();
        this.setupEnvironmentTexture('default')    
        this.setupDummyMesh();    
    }

    animate() {
        this._pathTracer.renderSample(this._scene, this._camera);
    }
}

const measurement = new Measurement();
measurement.setup()

CodeSandBox Link: https://codesandbox.io/p/sandbox/kz7x95

When samples are 0:
image

When samples become more than 0:
image

Platform:

  • Device: Desktop
  • OS: Windows
  • GPU: NVidia
  • Browser: Chrome
  • Browser Version: 129.0.6668.103 ( 64-bit )
  • Three.js version: ^0.169.0
  • Library version: ^0.0.23

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions