-
-
Notifications
You must be signed in to change notification settings - Fork 35.9k
Closed
Description
Description
When working at WebGPURenderer
support for GLTFExporter
, it was noticed that a certain asset introduces rendering issues with the WebGPU backend (see #29509 (comment)). With WebGL, everything renders as expected. The problematic file is models/gltf/ShaderBall.glb
which uses normalized (and interleaved) buffer attributes. For some reasons, the mesh itself or other meshes in the scene can end up distorted.
Reproduction steps
- Open one of the fiddles.
- The scene should render two meshes (
ShaderBall.glb
and a torus knot). - Notice how the torus knot is distorted.
Code
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
let camera, scene, renderer;
init();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
camera.position.set( 0, 1, 5 );
scene = new THREE.Scene();
//
const ambientLight = new THREE.AmbientLight( 0xcccccc );
scene.add( ambientLight );
const dirLight = new THREE.DirectionalLight( 0xffffff, 3 );
dirLight.target.position.set( 0, 0, - 1 );
dirLight.add( dirLight.target );
dirLight.lookAt( - 1, - 1, 0 );
scene.add( dirLight );
//
const loader = new GLTFLoader();
loader.load( 'models/gltf/ShaderBall.glb', function ( gltf ) {
const model = gltf.scene;
model.position.set( - 2, - 1, 0 );
console.log( model );
scene.add( model );
const material = new THREE.MeshStandardMaterial( {
color: 0xff0000,
roughness: 1
} );
const object = new THREE.Mesh( new THREE.TorusKnotGeometry(), material );
object.position.set( 2, 0, 0 );
scene.add( object );
} );
//
renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
document.body.appendChild( renderer.domElement );
const controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 2;
controls.maxDistance = 10;
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
renderer.render( scene, camera );
}
Live example
Screenshots

Version
r169
Device
Desktop
Browser
Chrome
OS
MacOS