Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: sub-ranged texture() in GLSL

  1. #1
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    595

    sub-ranged texture() in GLSL

    The basic idea of this suggestion is to make texture atlasing less awful to do. Create (another!) texture function of the form:

    Code :
    texture(sampler2D T, vec2 p, vec4 rect)

    which does the sampling restricted to rect (encoded as .xy=position withing texture and .zw=size within texture) i.e. the texture coordinate p is relative to rect. Without filtering, it is equivalent to

    Code :
    texture(T, p, rect) == texture(T, rect.xy + rect.zw*p)

    with filtering is where it is useful, texels on the boundary of rect get filtered with the texel on the opposite size for repeat, and with itself for mirror repeat, mirror and clamp. Extending, I want this:

    Code :
    enum RepeatMode
    {
        mirror,
        repeat,
        clamp,
        mirror_repeat
    }
     
     
    texture(sampler2D T, vec2 p, vec4 rect, enum RepeatMode mode);

    this does fit in with mipmapping and gives what you want IF both:
    • the texel-size of rect is a power of 2 AND
    • the boundary of rect is a multiple of the size of rect



    Naturally this above can be logically extended to textureLod, textureGrad, textureProj, textureProjGrad, texture arrays, 1D textures, 3D textures, and texture rectangles. [3D textures will needs that the rect is a cube].

    As a side note, it is debatable if it is also worth adding another enumeration argument stating if the filtering is linear or nearest. [mipmap filtering is essentially handled by LOD, though one can argue the filtering between mip maps also needs to be specified].

    One can naturally emulate this doing the filtering by hand in shader using texelFetch, but that seems like an unnecessary burden on a developer and a potential optimization lost on the hardware.
    Last edited by kRogue; 09-18-2012 at 01:23 AM.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,128
    Kind of cool. Except for the restriction on POT rects. This partly crippels the only real advantage texture atlases still have over texture arrays, i.e. textures of arbitrary sizes packed into a single NPOT texture. Am I missing something?

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    595
    The thing would still just work even if the rect is not a power of 2 in size and such, but things get ugly when higher LOD's are accessed. Take an example as follows:

    Real Texture is say 4 texels long, say the contents of the entire texture is:

    | A | B | C | D |

    then with a typical box filter (on 1D) would give this:

    LOD1: | (A+B)/2 | (C+D)/2 |
    LOD2: | (A+B+C+D)/4 |

    now lets say the sub-rectangle is length 2 starting at texel 1 instead of texel 0, then we would want that:

    LOD0: | B | C |
    LOD1: | (B+C)/2 |

    which for LOD1 that texel value does not even exist. Going further what happen if we feed a texel coordinate on the boundary of B and C under GL_LINEAR_MIPMAP_NEAREST for minification and GL_LINEAR for magnification:

    textureLod(, 0) --> (B+C)/2 which is what we want
    textureLod(, 1) --> (A+B+C+D)/4, the average of (A+B)/2 and (C+D)/2

    i.e. the mips leak. If we do not have mipmap filtering then no worries, if the sub-rectangle is a power of 2 and if it "starts" on a multiple of its size, then the mip maps won't leak either.

    I am not advocating that the rect argument of the new function needs to be power-2 jazz, but saying that mip-maps will bleed from outside the rectangle.

    Along these lines, I guess another function worth considering is to have texture() also get passed the maximum LOD allowed to be fetched, so for example if a sub-rect is say 13 texels long and starts at say texel 3, then the mip does not leak until LOD=2 for example....

  4. #4
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    985
    Quote Originally Posted by kRogue View Post
    One can naturally emulate this doing the filtering by hand in shader using texelFetch, but that seems like an unnecessary burden on a developer and a potential optimization lost on the hardware.
    Well, the only problem is that current hardware wouldn't be able to use hardware filtering of textures within an atlas, otherwise this would have been there for a long time. The only benefit you would get is that you don't have to write the filtering code yourself which doesn't justify adding this feature to GLSL.

    What would be a better and cleaner method is if we would have texture arrays that can have layers arbitrary sizes. However, I don't think that there's hardware support to that either. The closest functionality may be NVIDIA's bindless textures what you can use to emulate such a texture array by having an array of samplers stored in a buffer.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    595
    Well, the only problem is that current hardware wouldn't be able to use hardware filtering of textures within an atlas, otherwise this would have been there for a long time. The only benefit you would get is that you don't have to write the filtering code yourself which doesn't justify adding this feature to GLSL.
    I don't know if that is true, regardless, within the rectangle there is nothing to do, the only issue is on the rectangle boundaries.. and then it comes down to what is doing the filtering and how flexible it is....the textureFooOffset functions can also be emulated in GLSL, and they were added anyways..likely because the GL3 generation hardware could do it faster because of some extra magics.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •