-
-
Couldn't load subscription status.
- Fork 145
Description
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:
- The first material of the material array is applied to the entire Mesh, basically ignoring the rest of the material array
- 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:
- When we clear the groups and then construct our own groups
- 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
- 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
- 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 become more than 0:

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
