NPOT Texture, here 2^n + 1, disadvantages ?

Started by
9 comments, last by Green_Baron 4 years, 5 months ago

I will need a texture size of 2^n +1 or +2, with 2^n as far as i can see between 512 and 2048. These textures represent heightmap tiles and are intensively sampled from. They are not mipmapped, but will be compressed via opengl built-in compression.

This is needed because i calculate normals via weighting/interpolating neighbours and sobel filtering for graphical effects and edge detection, so that, if two such textures meet, they overlap by one. Otherwise (as it is now) the normals along the edges where a neighbour of the current texel is missing would be incorrect. Otoh, my lod algorithm and its quadtree structure demand a power of two size of a tile.

Officially this should work with only few "slightly unintended consequences", but is there a high risk of performance (texture lookup) or memory storage disadvantage (eventually padding by the driver) you'd know of ? Are thre any concrete "unintended consequences" ? i should be aware of ?

Advertisement

What are the filterings you use on those textures if any?

If those textures will be subjected to minification you will have a serious performance hit without mipmaps + artefacts, but I gues they'll be not?

I have a little doubt. Why a npot of 2^n+1 (+2) and not a texture rectangle ? 

To my opinion NPOT textures are old enough now, graphic cards and drivers should then be optimized enough both from memory occupation and lookup.

Why such performance and memory concerns ?

11 minutes ago, JohnnyCode said:

What are the filterings you use on those textures if any?

Default sampler is set to linear filtering and values clamped to edge. They are single channel float textures.

11 minutes ago, JohnnyCode said:

If those textures will be subjected to minification you will have a serious performance hit without mipmaps + artefacts, but I gues they'll be not?

Nope. I just sample from them.

13 minutes ago, _Silence_ said:

I have a little doubt. Why a npot of 2^n+1 (+2) and not a texture rectangle ? 

Good question. I could use a rectangle as well, would have to rethink my offsets and scaling into the texture then because of texel wise addressing instead of 0..1 ... is there a special reason that you suggest a rectangle over a 2d texture ?

13 minutes ago, _Silence_ said:

To my opinion NPOT textures are old enough now, graphic cards and drivers should then be optimized enough both from memory occupation and lookup.

That was my thought as well.

13 minutes ago, _Silence_ said:

Why such performance and memory concerns ?

I don't have specific reasons to be suspicious ....

I haven't run it yet. Before being able to actually try i must adapt my conversion routine for heightmap textures to generate the new sizes and change the offsets in the shaders. So there are probably a few off-by-one errors waiting for me :-)

 

5 hours ago, Green_Baron said:

Good question. I could use a rectangle as well, would have to rethink my offsets and scaling into the texture then because of texel wise addressing instead of 0..1 ... is there a special reason that you suggest a rectangle over a 2d texture ?

Don't know. This depends on your needs. Both have very different behaviors. Texture rectangles also have limitations (no mipmapping for example). But if you are dealing about exact pixel size, then this sounds that texture rectangles might be the best choice. So why these +1 or +2 pixels are in matter ? Are you doing pixel-precise treatments ? In the shaders are you using texture functions or gather functions ? These extra pixels will be interpolated and mixed during magnification or minification. Is this a concern ? Thus the will to understand what exactly are those extra pixels. I currently suppose this is related to the fact that your use tiling.

 

Hope i don't confuse things, have spoent the afternoon constructing related textures but with different content ...

1 hour ago, _Silence_ said:

But if you are dealing about exact pixel size, then this sounds that texture rectangles might be the best choice.

Well, it is not that the distance between texels directly corresponds to world positions. A texel is just a height value, it's world position comes from other sources and is calculated. But i don't want to go deeper into the LOD algorithm, will do that in my blog one day soon(tm). A rectangle texture might only have advantages if it is faster than a full blown 2d texture, but i'd consider tackling and comparing this to be premature optimization at the current state of program.

Quote

So why these +1 or +2 pixels are in matter ?

A vertex (world position) has one corresponding height value (a pixel if you so want, i'd prefer heightmap texel here). I calculate surface normals (vertex normals) in the vertexshader by sampling around the current position and crossing the resulting vectors, or by using a weighted matrix on the surrounding positions. Since a position and a texel correspond, i can do so easily. But there is a problem at the borders because texture positions are missing there. The resulting error is visible. That's why i need a texture of 2^n +1 or +2 depending on the normal calculation method.

Quote

Are you doing pixel-precise treatments ?

Nope, the resulting world positions are mangled so that they fit an ellipsoid. I am currently doing that.

Quote

In the shaders are you using texture functions or gather functions ?

Simple texture lookups. Example (simplified):


vec3 computeNormalCentralDifference( vec3 pos ) {
	float leftHeight = texture( heightMap, vec2( pos.x - 1.0, pos.z ) );
    vec3 left = vec3( pos.x - 1.0, leftHeight, pos.z );
	float rightHeight = texture( heightMap, vec2( pos.x + 1.0, pos.z );
    vec3 right = vec3( pos.x + 1.0, rightHeight, pos.z );
	float bottomHeight = texture( heightMap, vec2( pos.x, pos.z - 1.0 );
    vec3 bottom = vec3( pos.x, bottomHeight, pos.z - 1.0 );
    float topHeight = texture( heightMap, vec2( pos.x, pos.z + 1.0 );
    vec3 top = vec3( pos.x, topHeight, pos.z + 1.0 );    
    return cross( right - left, top - bottom );
}
Quote

These extra pixels will be interpolated and mixed during magnification or minification. Is this a concern ?

Mipmapping is disabled for the heightmap textures. Otherwise i'd have to call textureLod()s with another degree of complexity ... i am a stupid guy and would get lost ? And i wasn't exactly honest, a number of vertices can actually share adjacent heightmap values (faking resolution), and then interpolation takes place. But that is an independent thing.

Quote

Thus the will to understand what exactly are those extra pixels. I currently suppose this is related to the fact that your use tiling.

I need extra pixels or texels at the border simply because for the shading i want to sample around the current position (like in the example) and the underlying lod algorithm needs a power of 2 heightmap. Thus i must add the mentioned overlap of 1, either at one side and top, or at both sides, depending on the sampling technique. That's all.

I will simply go the way. If "unintended consequences" show up, i'll post them.

Thanks for sharing thoughts !

 

Block compressed formats generally require padding to a multiple of the block size, so 4x4 for BC/DXT/S3TC formats. Other than that, modern desktop hardware generally doesn't have restrictions or issues for non-power-of-2 textures as long as you don't have mipmaps. 

I think, POT make it friendly for texture look up operation (which is in binary floating point). Nowadays NPOT might not take as much hit as what in the past.

I think what's important is that the texture is sampled in 0.0-1.0 range not the integer postion like the bitmap operations. When you're saying that the texture has to be specifically 2^n+1 (or + 2) make it suspicious to me. It looks like you need the specific texel, which seems odds.

Personally I think you should be fine with 2^n+1/+2, and may be so even if you resize that texture to 2^n.

http://9tawan.net/en/

19 hours ago, Green_Baron said:

That's why i need a texture of 2^n +1 or +2 depending on the normal calculation method.

So I take it that you have fixed neighbourhood information in the texture resource itself.

This design allows you to pool your whatever quad textures together neighbouring in a one large POT atlas texture, allowing you to have mip-maps for LOD?

 

30 minutes ago, JohnnyCode said:

So I take it that you have fixed neighbourhood information in the texture resource itself.

Exactly, it is derived from lat/lon positions on an ellipsoid and a distance between posts expressed in degrees. Just another planet renderer (yawn).

Quote

This design allows you to pool your whatever quad textures together neighbouring in a one large POT atlas texture, allowing you to have mip-maps for LOD?

Correct in the first part, but the lodding is not done via mipmaps, it is a cdlod clone i use.

Edit/Correction: not one large height texture, it is far too large and may have white spots, but stitch together individual tiles based on their position.

This topic is closed to new replies.

Advertisement