I originally posted this question over at blenderartists.org: https://blenderartists.org/t/help-padding-uvs-uber-newb/1169171
I have not gotten any responses, so I though perhaps you super smart guys would know a good solution.
So I Introduced basic texture atlasing in a dev build of my game and all works pretty well (diffuse,normal,specular and even combining multiple geometries and using a single texture for all maps).
However of course as a consequence of this (beyond increased texture to gpu loading time, which I’ll get to in another post eventually), I am experiencing some uv bleed on a particular combined geometry (foliage and trunk are merged).
Ideally I would like to modify the foliage uv’s in blender to “ignore” the outer edges of the image. But to be honest I do not know how. I even tried a programmatic attempt by limiting uv values between a range of 0.02 and 0.98 for example, but no luck.
Does anyone know what I can do here? I know this isn’t three.js specific, apologies for that, but I am stuck =[
This is the texture:
235.gltf (20.8 KB)
I thought I understood the question but I was wrong. Can you post some example of your geometry (when merged) and it’s uv channel?
How did you limit them? Clamping will lose the outer edge completely. Shrinking all UVs symmetrically to within the range will offset textures slightly with respect to (nearly) all of their intended vertices. Hm.
Bad advice, sorry. See other users' remarks about mipmapping.
I guess the best result would be achieved by padding textures in the atlas (or, perhaps better, separating them only by a width 1 black border) while _also_ shrinking them correspondingly. An attempt at shrinking in GLSL "pseudocode":
vec2 wh = vec2(width, height);
uv_new = 0.5+((wh-2)/wh)*(uv_old-0.5);
//This assumes you will make the atlas afterwards. Thus "pseudo".
I can’t help but thinking that this bleeding must be possible to use for something cool? Especially on continuous, natural things like trees. Maybe you can find an ordering of the textures that makes the transitions look natural (with small adjustments to the pixel values)?
It’s bleeding from mipmapping, there are various ways to avoid the issue, im using 2 different techniques for the packing function since it deals with arbitrary texture tile sizes, while in your case it would be easier to use a array texture probably. Padding also helps. Using THREE.LinearFilter might be already good enough too with anti-aliasing.
I’ve tried padding the image manually by adding a transparent line (or 3) on the adjacent tree trunk images. This works but also makes some portions of the trunk transparent which of course won’t work.
I’ve also tried different filtering methods, but do not work 100%.
@Elias losing the entire edge of the foliage completely is exactly what I wish, but I haven’t had any luck.
@Fyrestar Texture arrays probably would work. Does three.js support these? Do you happen to know where I can find an example of this technique?
@pailhead I will have to export it via three.js as that’s where the geometry is merged. I will work on this.
BTW here is the texture file I am using:
OK so WebGl 2D texture arrays seem to be the solution (didn’t realize there was docs for this in three.js already). However webgl2 seems to disable all normal mapping using MeshPhongMaterial AND breaks the SPE particle library I use.
Looks like I have a lot of work to do (not to mention scrapping like a hundred hours of work getting the atlasing to work, oh well… learned a lot in the process =] ).
So ehh… do texture arrays have to be made of data textures or is it possible to use standard THREE.Texture?
You have no padding on the textures it seems. The leaves should have a lot of green around them coming from the pixels being expanded, along with some average color instead of white. The transition between the trunk and the leaves, i think you just have to move it at least a little bit. It wont work on all the mip levels, but it could behave better.
Each layer of a texture array is a pixel row, so you need to convert it.
Usually your tiles look like:
As texture array it basically is:
Problem is that the trunk texture bleeds into the outer edge of the transparent part of the foliage texture by a few pixels. I was thinking that if I could get the uv’s to ignore the outer most edges, but I think I would have to actually re uvmap the trunk part to achieve this, which I’d rather not.
I’m going to take stab at the 2d texture array solution, which is going to take some work as well, but feels less “hacky”.
Thanks, I’m going to take a stab at this over the next month or so.