why is texture border and GL_CLAMP deprecated ?!

I just discovered the border parameter in glTexImage2D which I find very useful for my needs (tiling a very large -4096x16384- texture in tiles of 2048x2048), and its associated GL_CLAMP mapping mode.

To my surprise, both are marked as deprecated in OpenGL 3.0, but I don’t see any feature that would replace it for tiling.

Is there any other way to tile large textures, while keeping smooth filtering from one texture to the next ?

GL_CLAMP is not very useful for seamless tiling if you don’t use borders. But if it suits you, then it’s OK. GL_CLAM_TO_EDGE is not deprecated, and, it is my humble opinion, will better serves your purpose.

You can implement seamless tiling in fragment shader.
I understand this is little bit more complicated then using GL_CLAMP and texture borders.

Check if the texture coordinate is on the edge, then emulate border by sampling neighbor texture. You would have to emulate linear filtering on the edge yourself.

implementing seamless tiling in fragment shader sounds extreme, it requires providing 9 textures unit (main texture+4 borders+4 corners) and a bit of math in the shader. Just to have some tiling.

I think I will just use a NPOT texture with 2 additionnal rows/columns for each border, and simulate appropriate texture coordinate depending on GL_CLAMP or GL_CLAMP_TO_BORDER.

You can have the border in one additional texture.
No need to have 8 of them.

but I agree that if the textures are not dynamic it can be prepared in CPU.

The funny thing is that they just added GL_CLAMP style filtering back in – but only for cubemaps: GL_ARB_seamless_cube_map.

Thus illustrating that there are conditions under which GL_CLAMP_TO_EDGE isn’t good enough for seamless tiling…

The funny thing is that they just added GL_CLAMP style filtering back in – but only for cubemaps: GL_ARB_seamless_cube_map.

That’s not what seamless cubemap does. What it does is allow the cubemapping to sample across texture boundaries, from the edge of one texture to the edge of another. It has nothing to do with GL_CLAMP.

Hi Alphonse,

To achieve seamless tiling with GL_CLAMP, you load the border texels with the just-inside-the border texels of the adjacent texture tiles. This allows the filtering sampling logic to work as if it were sampling from the adjacent tile.

Even better, you can pull this trick across all mipmap levels and is works perfectly because the 0…1 texture coordinates are always “just inside” the border texels.

This is effectively exactly what seamless cube map does. But the cube map logic is simpler because you don’t have to explicitly specify the border texels. They are implicitly defined by the edges of the other faces of the cube.

Although you can treat the outer ring of a non-bordered texture as a pseudo-border, by shrink your texture coordinates inward, this doesn’t work right for other mipmap levels, because the texture coordinates are not right.

I’m not saying you couldn’t use GL_CLAMP for other purposes (after all, nobody is forcing you to define the border texels that way). But you can’t get that seamless tiling effect across all mipmap levels with any other standard texture wrap mode.

Really GL_CLAMP was ingeniously designed – but apparently it solved a problem that didn’t need solving for most video games. [Edit: except for skyboxes :)].

This is effectively exactly what seamless cube map does.But the cube map logic is simpler because you don’t have to explicitly specify the border texels.

And it is that difference, that GL_CLAMP requires border texels explicitly specified by the application and seamless cube mapping doesn’t, that makes them entirely different. One of these is automatic, the other requires explicit work, takes up precious memory, and cannot be used with any form of texture compression.

One of these is automatic,


the other requires explicit work,

Only if you need to use it. And having a correct result is worth the little extra work.

takes up precious memory,

Are you kidding ?
Say you have a fully mipmaped 1024*1024 texels texture, this will only add 8232 texels for borders, about half percent of total texture…
The alternative is to manually duplicate content across textures and play with blended parts to hide seams. Talk about previous memory wasted.

and cannot be used with any form of texture compression

That is right, one would need a compression accepting 2-divisible textures, or not compressing borders at all.


maybe you should consider an entirely different approach.
Think about clipmapping, virtual texturing and the like.
That gives you many advantages: Its easier for you to draw the whole thing (no texture swapping, because no more tiles) and fixed texture memory footprint, regardless how big your real texture is. The runtime memory needed is only dependent on the screen resolution then. Also, you can make use of better filtering … I don’t know if your tiling approach (1 texel wide texture border) still works with anisotropic filtering.

And before you go bitting off those, consider just abutting standard, simple, easy, MIPmapped textures without border using CLAMP_TO_EDGE.

Is it perfect? No. But it looks pretty darn good. Plenty good enough in many cases. And when you consider virtual texturing hand-waves away hardware-accelerated MIPmaps entirely for texture filtering it’s less clear why you’d want the complexity and expense, at least for ver 1.

Dittos for clipmapping and the changes mandated for how you store and page terrain/texture off disk, and how it handwaves view-dependent LOD issues (distant mountain kinda ugly? :eek: Oops. Sorry.)

ZbuffeR, you’re missing the point.

The argument that I was responding to was that GL_CLAMP should be retrained because seamless cubemap does the same thing.

They are not similar, for the reasons I outlined. They do not do the same thing. They can do similar things, if you arrange your border texels right. GL_CLAMP causes filtering to sample from border textures, which can be used to have seamless tiling of multiple textures. Seamless cubemapping causes all cubemap sampling to happen across boundaries of the same image within a single texture.

They’re not similar at all. And so the argument that GL_CLAMP should be retained due to similarity with seamless cubemap is wrong.