Advertisement

Texture aspect ratio - Does it matter?

Started by February 03, 2018 05:55 PM
54 comments, last by cgrant 7 years ago
6 minutes ago, galop1n said:

If the only things that change between your draws are a few texture binding, you can push thousands of draw calls before you start to fill a cost here !

 

Do not forget, early optimisation is root of all evils. Unless you have decades of experirence at profiling GPUs and Graphics API, It is dangerous to jump into thinking something is fast or slow.

 

Make your render visually correct first, then optimize based on real profiling if it is needed only.

There is the cost of switching vertex and index buffers also, plus 3 different textures for each object and updating a constant buffer, plus the same thing all over again for each shadow map, it all adds up. I've been developing this engine for a few years now so it's not that early anymore. Need to make it lean. :) There will be a lot of stuff moving around anyway so batching the static part seems wise.

7 minutes ago, CarlML said:

There is the cost of switching vertex and index buffers also, plus 3 different textures for each object and updating a constant buffer, plus the same thing all over again for each shadow map, it all adds up. I've been developing this engine for a few years now so it's not that early anymore. Need to make it lean. :) There will be a lot of stuff moving around anyway so batching the static part seems wise.

Merging geometry and materials are two different things. And most materials for shadow map do not need the texture in the first place ( unless it does alpha clip ). 

 

It would require a few more info on what is your overall frame like to provide good pointers. We could write books on what is good and what is bad practice in a renderer, so If you are ok to share a renderdoc or nsight capture, i can give you some advice on what i will see concretely.

Advertisement
19 minutes ago, galop1n said:

Merging geometry and materials are two different things. And most materials for shadow map do not need the texture in the first place ( unless it does alpha clip ). 

 

It would require a few more info on what is your overall frame like to provide good pointers. We could write books on what is good and what is bad practice in a renderer, so If you are ok to share a renderdoc or nsight capture, i can give you some advice on what i will see concretely.

Currently I'm rendering parallax and alpha clipping in the shadow map but I might reserve that for static objects later, in a prerendered static shadow map. Anyway we can delve more into my engine progress at a later time.:) Thanks for the suggestions. I'm going to look into those texture arrays.

 

And thanks Scouting Ninja for taking the time to help out!

Skipped most of this :), but you can duplicate some texels to get the same effect as with tiling around a border, if your goal is just to avoid visible seams.

Those papers are complicated, but just look at the images to get the idea. If your models already have UV maps that appear seamless across the texture border, really all you need is to duplicate texels and transform the UV maps by simple constant scaling and offset.

http://alice.loria.fr/publications/papers/2010/SEAMLESS/seamless.pdf

http://pages.jh.edu/~dighamm/research/2004_01_sta.pdf

57 minutes ago, JoeJ said:

Skipped most of this :), but you can duplicate some texels to get the same effect as with tiling around a border, if your goal is just to avoid visible seams.

Those papers are complicated, but just look at the images to get the idea. If your models already have UV maps that appear seamless across the texture border, really all you need is to duplicate texels and transform the UV maps by simple constant scaling and offset.

http://alice.loria.fr/publications/papers/2010/SEAMLESS/seamless.pdf

http://pages.jh.edu/~dighamm/research/2004_01_sta.pdf

That becomes complicated when using parallax occlusion, as I stated, becuase you will view parts outside the texture area when viewing it at an angle in many cases. It is probably a deal breaker. When the texture has displacement at the edges of the texture, like in a terrain texture, I think you will need proper tiling in such cases.

 

I think there was some confusion about what I'm trying to achieve. The layout I'm proposing would look like this, where every square would have a unique texture that would tile with itself horizontally. It wouldn't tile with other parts of the atlas:

texturetile.jpg.79e20eb5dc53158e841ca66086caaf49.jpg

1 hour ago, CarlML said:

That becomes complicated when using parallax occlusion, as I stated, becuase you will view parts outside the texture area when viewing it at an angle in many cases. It is probably a deal breaker.

This should still work if you modify sampling coords in shader so they warp properly, and there are enough duplicated pixels to support filtering mode without artifacts.

But just to mention - i assume texture array works without issues.

Advertisement

To do atlasing you need border pixels equal to the size of the largest hardware texture filter that you use. If you don't use mipmaps and use bilinear filtering, that's 1px. If you use 5 mipmap levels, you need 32px borders. If you use anisotropic texture filtering, god knows how big your borders need to be.

To do tiling, you do pixel shader math to remap from virtual texture coordinates to atlas coordinates. Stuff like parallax mapping/etc doesn't change this.

Yes, if you arrange your atlas either horizontally or vertically, you can skip half the math / border pixels, because hardware wrapping will work on one axis. Having strange texture sizes probably won't cause any performance/memory usage issues, but you never know. GPU's have all sorts of very strange internal requirements when it comes to alignment of texture data (especially mipmap storage layouts). Examples of hypothetical strange hardware-specific rules include things like --
* width being rounded up to a power of two (so a 500x200 texture takes up the same space as a 512x200 texture),
* pitch being forced to a multiple of 1024 (so a 4 byte per pixel 200px wide texture has a horizontal pitch of 800 bytes, which gets rounded to 1024 bytes, or the same as a 256px wide texture)
* mipmap level 1 vertical pitch being rouned to a multiple of 4KB -- so a 500*200px, 4 byte per pixel image takes up 400000 bytes in mip0, which is 97.65625 4KB pages, so mip1 won't begin until the 98th 4KB page, wasting 1408 bytes.

These rules are crazy and often unpredictable. I have worked with hardware where a thin/tall texture was very much preferred over a wide/short texture, to the point where we made our tools emit warnings to the art team when making wide textures :D

Square, power of two textures are pretty safe in general though :) 

However, as mentioned earlier, you don't need atlases in most cases any more. You can just use a texture array and the hardware does everything for you.

38 minutes ago, JoeJ said:

This should still work if you modify sampling coords in shader so they warp properly, and there are enough duplicated pixels to support filtering mode without artifacts.

But just to mention - i assume texture array works without issues.

It might but the problem is, how do I know what uv's warp where if I have just one big static mesh that uses various parts of the atlas? I would have to store that per vertex and probably manually assign ID's to each face in the 3D program. I suspect it could get messy.

 

I'm going to look into texture arrays but I'm not liking the idea of having to manage 48 separate textures (16*3) for the main level object instead of just 3 (diffuse, normal, info). Texturing the level will be a lot more pleasant if I can just mix and match parts from one big texture atlas.

Thanks for the info Hodgman, yes I have noticed some of those peculiarities about byte alignment in non square 2 textures.

Perhaps having two 1024x8192 textures as a texture array would be a thing? 8192 is perhaps safer than 16384?

1 hour ago, CarlML said:

It might but the problem is, how do I know what uv's warp where if I have just one big static mesh that uses various parts of the atlas? I would have to store that per vertex and probably manually assign ID's to each face in the 3D program. I suspect it could get messy.

You would probably globaly use the same modulo, e.g. (1024-32*2), assuming you have 32 texels on the broders. I see to limitations in comparision to your intended wide or high large texture, which would have also only one constant width or height.

1 hour ago, CarlML said:

I'm going to look into texture arrays but I'm not liking the idea of having to manage 48 separate textures (16*3) for the main level object instead of just 3 (diffuse, normal, info). Texturing the level will be a lot more pleasant if I can just mix and match parts from one big texture atlas.

You mean it would limit creativity when level editing? You could automate this, the editor shows one large texture and a tool calculates slicing texture space and adapts UVs. It could even cut meshes if no good solution can be found. This should happen rarely enough to not affect performance.

(Note that i don't really know what you mean with parallax occlusion - in case that matters i might miss something.)

 

This topic is closed to new replies.

Advertisement