Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Materials are rendered wrong when using Material Array #675

Open
PratikHadawale-tech opened this issue Oct 23, 2024 · 0 comments
Open

Materials are rendered wrong when using Material Array #675

PratikHadawale-tech opened this issue Oct 23, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@PratikHadawale-tech
Copy link

PratikHadawale-tech commented Oct 23, 2024

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
@PratikHadawale-tech PratikHadawale-tech added the bug Something isn't working label Oct 23, 2024
@PratikHadawale-tech PratikHadawale-tech changed the title Materials are rendered wrong when using Material Array Materials are rendered wrong when using Material Array ( Link to CodeSandBox included ) Oct 23, 2024
@PratikHadawale-tech PratikHadawale-tech changed the title Materials are rendered wrong when using Material Array ( Link to CodeSandBox included ) Materials are rendered wrong when using Material Array Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant