Seams between tiles
1. You tiles should be of power of two size, this could prevent texture bleeding from mipmapping.
2. Try to use array textures: put each tile on a single layer (thought I don't know if the iphone supports this). Don't try to archive this with 3d textures (=>mipmapping issues)!
3. Try to clamp to the tile borders using a shader, add a small border to the tiles,but your total tile size(including border) should be still a power of 2.
u := ( x + 0.5 ) / texture_width_in_texels
v := ( y - 0.5 ) / texture_height_in_texels
(Notice please that 0.5 - y may be needed instead, dependent on how you define y to run over the texture.)
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)]3. Try to clamp to the tile borders using a shader[/background]
[/font][/quote]
Would you mind demonstrating how this works (preferably with a CG shader)?
vec2 texture_coord = ..input..
// retrieve fraction part of coords to map coord into [0..1]
texture_coord = fract(texture_coord);
// clamp to 1/2 pixel, i,e. DELTA = 0.5/1024.0 for 1024 texture, play around with values to see its effect, consider mipmaps, which halfs the resolution at the underlying level
texture_coord = clamp( texture_coord, vec2(0.0)+vec2(DELTA), vec2(1.0)-vec2(DELTA));
// shift and scale texture to according corner
texture_coord = texture_coord * vec2(0.5) + vec2(OFFSET_X,OFFSET_Y);
But I think, that you will archive better quality when using a border (repeating texture accordingly).
Also, the screenshots for Gnoblins look amazing, well done!
lower_left_uv.x += 1 / width;
lower_left_uv.y += 1 / height;
upper_left_uv.x += 1 / width;
upper_left_uv.y -= 1 / height;
upper_right_uv.x -= 1 / width;
upper_right_uv.y -= 1 / height;
lower_right_uv.x -= 1 / width;
lower_right_uv.y += 1 / height;
Whilst this seems to work (through trial and error) is there any logic to this?
thanks
If you have a 512x512 atlas made of 8x8 tiles each one with 64x64 pixel then instead of using a mipmap pyramid of log2(512)=9 levels. you have to use a mipmap pyramid of log2(64)=6 levels. And you have to care each single tile reducing it by few pixels (for example reduce down to 54x54) and fill the pixels around with extrusion of the tile. With farest geometries artifacts may still occurr, but with some fog are nicely hided. (you still need to readapt texture coordinates to 54x54 subtile instead of 64x64 subtile)
Texture arrays is still a valid alternative (i think TA were born for these problems).
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)]you need a incomplete Mipmap pyramid[/background]
[/font][/quote]
Are you saying that this applies when I have mipmapping disabled?
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)]Texture arrays is still a valid alternative (i think TA were born for these problems)[/background]
[/font][/quote]
Yes these would certainly improve matters because I could take a completely different route. Unfortunately ShaderLab (in Unity) does not provide bindings for sampler2DArray
disabling mip-mapping
Disabling mip-mapping is not the best idea. For one you will get strong artifacts when moving around and using detailed textures, and it is slower than using mipmapping.
Whilst this seems to work (through trial and error) is there any logic to this?
Yes, the reason is, that on a atlas the naive pixel coordinates are often between two adjacent textures. Therefore the samples taken at the border will include texture data from the adjacent texture (reason: linear filtering). To reduce the effect, you need to move your coord away to the center of the border pixel which you have done by moving it by a whole pixel away (half would be enough).
This could be done with lower mipmapping levels too, but in this case you need to move it away depending on the mipmap level, that is
level 0: 1/width
level 1: 1/ (width/2) = 2/width
level 2: 1/ (width/4) = 4/width
level 3: 1/ (width/8) = 8/width
...
As you can see, higher mipmap levels result in a relative broad border, so you can't just calculate it once and apply it to all levels. Either you need to ajdust it dynamically depending on the mipmap level (expensive, newer hardware needed) or you should repeat the border of your tile. As far as I remember the latter has been done in the id-tech5 engine (megatextures utilize lot of atlases).
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)]Disabling mip-mapping is not the best idea. For one you will get strong artifacts when moving around and using detailed textures, and it is slower than using mipmapping[/background]
[/font][/quote]
I don't think that is the case for me because I have an orthographic camera. Somebody suggested to me that there is very little advantage to mipmapping for 2D...
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif][background=rgb(250, 251, 252)]As you can see, higher mipmap levels result in a relative broad border, so you can't just calculate it once and apply it to all levels. Either you need to ajdust it dynamically depending on the mipmap level (expensive, newer hardware needed) or you should repeat the border of your tile. As far as I remember the latter has been done in the id-tech5 engine (megatextures utilize lot of atlases).[/background]
[/font][/quote]
Very interesting, thanks for pointing that out.