I’ve been generating some early concept art and product mockups using Nano Banana 2 Lite, a third-party independent browser-based image tool (unrelated to Google/DeepMind), just to sketch out visual ideas before building actual 3D assets. Now I want to bring some of these images into a Three.js scene as reference planes for lighting/composition studies, and I’m running into some texture quality issues.
The problem
When I load a PNG onto a PlaneGeometry with a basic MeshBasicMaterial, the image looks noticeably blurry once the camera moves close, but also shows visible aliasing/shimmer at a distance. I suspect I’m not handling mipmaps or filtering correctly.
Questions
colorSpace - should externally sourced images always be set to THREE.SRGBColorSpace on the texture, or does it depend on how the image was exported? I’m getting washed-out colors compared to the source PNG.
Filtering - for reference planes viewed at varying distances, is LinearMipmapLinearFilter for minFilter and LinearFilter for magFilter the right combo, or should I be generating mipmaps manually for non-power-of-two images?
Aspect ratio - what’s the cleanest way to preserve the original image aspect ratio on the plane without manually calculating geometry dimensions every time?
Transparent PNGs - any gotchas with alpha channels and transparent: true causing z-fighting or sorting issues with multiple overlapping reference planes?
Any code snippets or links to relevant three.js examples would be appreciated. Trying to avoid reinventing this if there’s a standard workflow already documented somewhere.
Yes, most of the times, you need THREE.SRGBColorSpace to get the colors you have on the image. Only rarely did I explicitly chose otherwise!
Three.js handles “non-power-of-two” images very well. The default works for most situations! You only need to change that if you want the texture to look sharp (and mostly pixelated) or you have a specific use case for it with shaders.
if you know the image ratio, you set it once on the geometry and change the scale if you want it to look bigger. If you image is 16:9 for example, you set the plan geometry’s height to 1, and width to 1 * 16 / 9. In case you have many images with different ratios, you would need to create a function that takes the image, gets the pixels out of the image and calculates the ratio, and finally return the geometry. That is complicated, but was the best option when I needed it (not sure if there is a better way!)
Overlapping plans (without transparency) are problematic and will cause z-fighting! And almost always, it is inconsistent (works fine on PC, but look wild on phones, or vise versa!) The most efficient solution was always to give the layers a little distance, say 0.01. Other than that, you need to understand what depthWrite, depthTest, and alphaTest do. They will save your sanity sometimes!
Now, back to your problem. Using MeshBasicMaterial is the standard way to do what you need (no lights at all). But make sure in your code that…
you have set THREE.SRGBColorSpace on the texture
the source image quality is good
the renderer have anti-aliasing
no tonemapping
You can/should also test your textures on Three.js editor (it is a web-based tool using Three.js of course! If you can load and see you image there, washed out too, then the problem is deeper than what I think!)
Sharing the code and/or example images will make things much clearer for us to understand the problem and help you with a much more accurate steps. And if you can share the source textures too, that will be great.