three.js icon indicating copy to clipboard operation
three.js copied to clipboard

DataTexture issue introduced in r145

Open Usnul opened this issue 1 year ago • 1 comments

Description

I was upgrading my virtual texture system to the latest revision up from r136, going directly to current version (r167.1) yielded a curious error:

WebGL: INVALID_OPERATION: texSubImage2D: no texture bound to target
GL_INVALID_OPERATION: Invalid combination of format, type and internalFormat.

I looked deeper and found that the problem was coming from copyTextureToTexture:

image

So I started looking for the point where the breakage occurs, r144 is fine, r145 breaks.

Looking through the patch notes yield little of interest except for:

  • https://github.com/mrdoob/three.js/pull/24492
  • https://github.com/mrdoob/three.js/pull/24599

and possibly https://github.com/mrdoob/three.js/pull/24637

Here's the actual code that sets up the offending texture:

#page_texture = new DataTexture(
        new Uint8Array(4096 * 4096  * 4),
        4096 ,
        4096 ,
        RGBAFormat,
        UnsignedByteType,
    );

/* ... */

const texture = this.#page_texture;

texture.unpackAlignment = 4;

texture.type = UnsignedByteType;
texture.format = RGBAFormat;
texture.internalFormat = "RGBA8";

texture.generateMipmaps = false;

texture.minFilter = NearestFilter;
texture.magFilter = LinearFilter;

texture.wrapS = ClampToEdgeWrapping;
texture.wrapT = ClampToEdgeWrapping;

texture.anisotropy = 8;

All of the above is done in the constructor of the containing class, so all parts are done before first usage.

The texture is bound to two custom shaders: image

here's what that looks like in r144: image

Nothing special there really, but perhaps important is the fact that these two use different ShaderMaterials, because if I comment out uniform assignment for one of the shaders (the one used for central element), the error goes away:

image

The console is clean too.

My best guess is that when textures.setTexture2D( dstTexture, 0 ); is being called inside copyTextureToTexture, it binds / activates the wrong texture. Why? - no idea.

Version

r167.1

Device

Desktop

Browser

Chrome

OS

Windows

Usnul avatar Aug 17 '24 21:08 Usnul

@usnul I was so excited about your virtual texture project that I got to work and also developed a system like that. I started this on r160 and it works fine. Thanks for the inspiration

Here I made a very simple test in codePen with r167.1 https://codepen.io/Spiri0/pen/WNqMEvr?editors=0010

Therefore copyTextureToTexture and DataTexture work. Of course I can only speak for r160 upwards, as I had never used copyTextureToTexture in three.js before r160. Your DataTexture looks completely normal 🤔 strange that it doesn't work.

P.S. I tried using your DataTexture setting in codePen, i.e. the filters without THREE. to use. Then it doesn't work anymore. Maybe that's the cause. This is how the codePen example works again:

texture2.minFilter = THREE.NearestFilter;
texture2.magFilter = THREE.LinearFilter;
texture2.wrapS = THREE.ClampToEdgeWrapping;
texture2.wrapT = THREE.ClampToEdgeWrapping;

Spiri0 avatar Aug 19 '24 05:08 Spiri0

@Mugen87 I think this point can also be closed. I checked it out with my WebGL VT system with r175.

Bild

in the past the usage of copyTextureToTexture was: renderer.copyTextureToTexture( position, srcTexture, dstTexture );

meanwhile it is: renderer.copyTextureToTexture( srcTexture, dstTexture, null, position );

If I omit the null I also get a black screen without any error messages in the console. My mini CodePen here works, too. I don't remember when the change happened in threejs. But I do remember that copyTextureToTexture was redesigned. I actually only work with WebGPU these days, but I still have my first test version of my VT system in WebGL2 and just tested it with r175. I had to adjust my usage of copyTextureToTexture, but then it worked just as before.

Spiri0 avatar Apr 12 '25 06:04 Spiri0