DataTexture issue introduced in r145
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:
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:
here's what that looks like in r144:
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:
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 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;
@Mugen87 I think this point can also be closed. I checked it out with my WebGL VT system with r175.
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.