Hi All, I’m getting started with copyTextureToTexture in a scene that loads lots of images and paints each to a shared texture.
What’s odd, though, is that after the textures are copied, the relevant region of the updated texture appears quite dark until the camera is close to the sprite that displays that texture. E.g. in the scene below, you can see that the texture is quite dark until the camera gets close to the cell:
Does anyone know what might be causing this? I’m using rawshadermaterial but there’s nothing fancy going on in there–just fetching the texture from a uniform atlas. I was previously updating a canvas and passing that as the uniform to the scene and this dark shading problem wasn’t happening–it only started when I switched from the canvas updating method to copyTextureToTexture.
Any suggestions others can offer would be hugely appreciated!
Maybe this is a strange question, but are you sure the texture block looks good once you have zoomed in? Dimness issues could be related to gamma correction etc., but I wouldn’t expect to see different results on different ranges…
A-ha! How about mipmaps? If the filtering interpolates between the full-resolution image and the next mip level, which is at the time not updated with a downscaled version of the new texture block…
Yes, the texture looks as expected when I’m zoomed in. The texture is just displaying a little image that’s 128px in one dimension (either height or width) and <= 128px in the other dimension, and right now those little thumbs are a little grainy in the actual jpg file that’s loaded, so the texture looks as expected when the camera is zoomed in.
The mipmap idea is interesting–I see how this could muck things up. Is it possible to disable the use of mipmaps altogether? I tried setting:
// cell is an object with a canvas context
cell.ctx.drawImage(img, 0, 0);
//this.cell.texture.generateMipmaps = false;
//this.cell.texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
cell.texture.minFilter = THREE.LinearFilter;
cell.texture.magFilter = THREE.LinearFilter;
cell.texture.needsUpdate = true;
// pass the data from the cell texture to the lod texture
renderer.copyTextureToTexture(coords, cell.texture, tex.texture);
I’m still seeing the strange darkness though. Is there another line of investigation I can try?
cell.texture.minFilter = THREE.LinearFilter;
cell.texture.magFilter = THREE.LinearFilter;
cell.texture.needsUpdate = true;
// pass the data from the cell texture to the lod texture
setTimeout(()=>renderer.copyTextureToTexture(coords, cell.texture, tex.texture), 500);
I am asking because I think the copy will be done before the texture update otherwise. If renderer.copyTextureToTexture does not check texture.needsUpdate and update the texture before copying, you will probably have the same problem with your code above, but possibly not with the timeout version. This would be an issue with renderer.copyTextureToTexture, and should probably be reported. I don’t have time to check the source code now.
It calls textures.setTexture2D on the destination texture, which internally checks texture version (needsUpdate). Hmm, so no luck on that either, I think… Please don’t assume that’s the end of the story! (I mean, it may still be worthwhile to pursue the timeout test, just in case. And definitely the mipmap lead.)