Skip to content

WebGPURenderer: Mipmaps are not generated correctly for the WebGPU backend. #31143

@ligaofeng0901

Description

@ligaofeng0901

Description

In my app, I use RenderTarget to render some scenes, and store each result to FrameBufferTexture. I found the behaviors of texture sampler is different of the two backends. The webgl backend is ok, the webgpu backend turns out a wrong result. It seems that then value of uv is more bigger than 1, the result of sampler is darker.

Reproduction steps

Code

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

let mesh, renderer, scene, camera, controls;

init();

const rtSize = 64;
let _rt = new THREE.RenderTarget(rtSize, rtSize, {
  depthBuffer: false,
});
const _camera = new THREE.OrthographicCamera(-0.5, 0.5, 0.5, -0.5, 0, 1);

let _mesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1, 1, 63), new THREE.MeshBasicMaterial({
    color: new THREE.Color(1, 1, 1),
}));
console.log(_mesh.geometry);

const _textureLoader = new THREE.TextureLoader();

function init() {

    // renderer
    renderer = new THREE.WebGPURenderer({
    	forceWebGL: false
    });
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setAnimationLoop( animate );
    document.body.appendChild( renderer.domElement );

    // scene
    scene = new THREE.Scene();
    scene.background = new THREE.Color( 0x000000 );
    
    // camera
    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set( 0, 0, 20 );

    // controls
    controls = new OrbitControls( camera, renderer.domElement );
    
    // ambient
    scene.add( new THREE.AmbientLight( 0x222222 ) );
    
    // light
    const light = new THREE.DirectionalLight( 0xffffff, 1 );
    light.position.set( 20,20, 0 );
    scene.add( light );
    
    // axes
    scene.add( new THREE.AxesHelper( 20 ) );

    // geometry
    const geometry = new THREE.PlaneGeometry( 12, 12, 8 );
    
    // material
    const material = new THREE.MeshBasicMaterial( {
        color: 0xffffff, 
        map: null,
        // flatShading: true,
        // transparent: true,
        // opacity: 0.7,
    } );
    
    // mesh
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    
}

let x = 1230;
let loadingCount = 0;
function animate() {

    if (loadingCount <= 1) {
        loadingCount++;
        x++;
        const url = `https://ecn.t0.tiles.virtualearth.net/tiles/a132100120.jpeg?g=13651`;

        _textureLoader.load(url, texture => {
            texture.colorSpace = THREE.SRGBColorSpace;
            const oldTexture = mesh.material.map;
            let oldRenderTarget = renderer.getRenderTarget();
            let outputTexture = new THREE.FramebufferTexture(rtSize, rtSize);
            outputTexture.repeat = new THREE.Vector2(15, 15);
            outputTexture.generateMipmaps = true;
            outputTexture.minFilter = THREE.LinearMipmapLinearFilter;
            outputTexture.magFilter = THREE.LinearFilter;
            outputTexture.name = 'output-' + x;
            _mesh.material.map = texture;
            // _mesh.material.needsUpdate = true;
            renderer.setRenderTarget(_rt);
            renderer.clear();
            renderer.render(_mesh, _camera);
            renderer.copyFramebufferToTexture(outputTexture);
            renderer.setRenderTarget(oldRenderTarget);

            mesh.material.map = outputTexture;
            mesh.material.needsUpdate = true;
            if (oldTexture) {
                oldTexture.dispose();
            } 
            texture.dispose();
            setTimeout(() => {
                // loadingCount--;
            }, 5000);
            
        });

    }
    renderer.render( scene, camera );

}

Live example

looks these two examples. the only differenece is the parameters forceWebGL of WebGPURenderer.
(https://jsfiddle.net/ligaofeng0901/nqjxd3r1/19/) forceWebGL is false. the color is darker.
https://jsfiddle.net/ligaofeng0901/nqjxd3r1/20/ forceWebGL is true. the color is normal.

Image

Image

Screenshots

No response

Version

r176

Device

Desktop

Browser

Firefox, Chrome

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions