gkjohnson / three-gpu-pathtracer

Path tracing renderer and utilities for three.js built on top of three-mesh-bvh.
https://gkjohnson.github.io/three-gpu-pathtracer/example/bundle/index.html
MIT License
1.33k stars 132 forks source link

Changing map result in a black one. #452

Closed clemimki closed 12 months ago

clemimki commented 1 year ago

Hello, I was trying to load a new texture dynamically and set it as a base color map of any material. I'm able to load the texture correctly and assign it to the material.map but it result as a black one when rendering using path tracing. The texture is correctly loaded and displayed when disabling the path tracing.

I'm changing the texture this way:

const newMaterial = new THREE.MeshPhysicalMaterial({
    color: 0xffffff,
    roughness: 0.5,
    map: new THREE.TextureLoader().load( new URL('stone_wall.jpg', import.meta.url).href )
});

pathTracer.gltfScene.traverse((c) => {
    if (c.isMesh){
        c.material = newMaterial;
    }
});

pathTracer.updateMaterials();

then I update the path tracer this way :

async updateMaterials(){
    const generator = new PathTracingSceneWorker();
    const { bvh, textures, materials, lights } = await generator.generate( this.gltfScene );

    const material = this.ptRenderer.material;
    material.materials.updateFrom( materials, textures );
    this.ptRenderer.reset();
}

Here without any pathtracing: image And here with pathtracing: image

I trying to edit the "materialDatabase.html" demo by overriding a material with a map instead of only changing basic parameters and same results, the material goes full black as soon as a texture has been added.

Am I missing something ? Thank you in advance.

Expected

The texture should be visible and rendered using path tracing.

Platform:

gkjohnson commented 1 year ago

Why did you delete the portion of the report template that requests a screenshot and model? Please provide a working example, as well, otherwise no help can be provided.

clemimki commented 1 year ago

I edited my message and added screenshots. I thought the description was enough. Any idea why it's not working ?

clemimki commented 12 months ago

I finaly founded the solution it came from the texture loading, the TextureLoader().load() is asynchronous and I had to put the update in the "onLoad" function like this.

new THREE.TextureLoader().load( 'stone_wall.jpg', texture => {
        const newMaterial = new THREE.MeshPhysicalMaterial({
            color: 0xffffff,
            roughness: 0.5,
            map: texture
        });
        pathTracer.gltfScene.traverse((c) => {
            if (c.isMesh){
                c.material = newMaterial;
            }
        });
        pathTracer.updateMaterials();
});