-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
WebGPURenderer: wrong update of compressed textures #29786
Comments
I updated the links to show an example of textures displaying wrong as well. |
Just a minor addition, support for one of the texture formats also appears to be missing. This could be tested by using the fiddle and changing the initial texture from 0 to 1 and then 2 and then 3 (this last one should show the error related to |
The compression format is properly supported and works as expected when the texture is initialized, for example: const textureNode = THREE.texture(textures[3]); However, the issue seems to be that the WebGPURenderer or the NodeBuilder doesn't yet handle dynamic reassignment of the compressedTexture format. |
@RenaudRohlinger I am not an expert for these things but that texture seems to be causing some issues. You and @vlucendo could try the following code in the WebGPU fiddle, which is using a different texture and is also disposing of each texture. It seems to work fine for switching all 4 textures but I am not sure how accurate it is. import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'
let mesh, renderer, scene, camera;
init();
async function init() {
// renderer
renderer = new THREE.WebGPURenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild( renderer.domElement );
// wait for renderer
await renderer.init();
// scene and camera
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, 20 );
// mesh
const geometry = new THREE.SphereGeometry( 5, 64, 32 );
const material = new THREE.MeshBasicNodeMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// bug report
// create loader
const loader = new KTX2Loader();
loader.detectSupport(renderer);
loader.setTranscoderPath('https://unpkg.com/three/examples/jsm/libs/basis/');
// load texture
const textures = await Promise.all([
loader.loadAsync('https://threejs.org/examples/textures/compressed/2d_uastc.ktx2'),
loader.loadAsync('https://threejs.org/examples/textures/compressed/2d_etc1s.ktx2'),
loader.loadAsync('https://threejs.org/examples/textures/compressed/sample_uastc_zstd.ktx2'),
loader.loadAsync('https://threejs.org/examples/textures/compressed/sample_etc1s.ktx2'),
]);
const compressedTexture = new THREE.CompressedTexture();
const textureNode = THREE.texture(compressedTexture);
// create color node
const getWGSLTextureSample = THREE.wgslFn( `
fn getWGSLTextureSample( tex: texture_2d<f32>, tex_sampler: sampler, uv:vec2<f32> ) -> vec4<f32> {
return textureSample( tex, tex_sampler, vec2f(uv.x, 1.0 - uv.y) );
}
`);
material.colorNode = getWGSLTextureSample( { tex: textureNode, tex_sampler: textureNode, uv: THREE.uv() } );
// assign first texture before render. if the texture on index 2 is selected first, none updates
compressedTexture.copy(textures[0]);
// change texture periodically: it should change 4 times but only changes 3 and has visual errors
let textureIndex = 0;
setInterval(() => {
textureIndex = (textureIndex + 1) % textures.length;
compressedTexture.dispose();
compressedTexture.copy(textures[textureIndex]);
compressedTexture.needsUpdate = true;
}, 500);
// start animation
renderer.setAnimationLoop( animate );
}
function animate() {
renderer.render( scene, camera );
} |
Just to mention that, with respect to the current code of the KTX2 Loader, this might not really be an issue but just a wrong approach to treating all returned textures as Even though the documentation suggests that the The WebGPU fiddle's code seems to specifically treat them all as const compressedTexture = new THREE.CompressedTexture();
const textureNode = THREE.texture(compressedTexture); As stated before, I am not an expert for these things and will leave it to the experts to figure it out. |
KTX2Loader was returning a The WebGPU version still seems to have issues, updating 2 times instead of 4. Doing Some loaders in core ( |
As a wild guess, maybe those could be 2 things that require correction:
|
Description
Updating compressed textures with the contents of others of different formats by copying them fails sometimes and have visual errors, but the same functionality works fine in WebGL. This functionality is often used when creating an empty texture while the asset loads, and then copying the loaded data to it once it's available.
I created a couple of fiddles with webgpu and webgl to compare. Webgpu only updates 3 times instead of 4 and displays a wrong texture.
Reproduction steps
(see fiddles)
Code
See fiddles
Live example
Screenshots
No response
Version
r170
Device
Desktop
Browser
Chrome
OS
Windows
The text was updated successfully, but these errors were encountered: