laptop graphics, arithmetic, shaders, fractals, demoscene and extra
Downside
Some of the typical issues with texture mapping of enormous surfaces is the seen repetition of the feel. Whereas issues like GL_ARB_texture_mirrored_repeat may also help alleviate the issue a bit by making the interval of repetition twice larger, the {hardware} can not clear up the issue by itself. Nevertheless, if we’re okey with paying the price of greater than a single texture fetch per pattern, then there are fairly first rate methods to forestall texture repetition. I’ll current 3 completely different methods.
The feel to be tiled
Common texture tiling with GL_REPEAT
The proposed options with “Approach 1”
Approach 1
One solution to forestall the visible repetition of the feel is to assign a random offset and orientation to every tile of the repetition. We are able to do this by figuring out through which tile we’re, making a collection of 4 pseudo-random values for the tile, after which utilizing these to offset and re-orient the feel. Re-orientation may be one thing so simple as mirroring in x or y or each. This produces a non repeating sample over the entire floor.
The approach simply described comes with some caveats that must be solved: First, the sample will present seams throughout the tile boundaries, because the otherwise offseted texture tiles will not match on the tile borders. Secondly, due to the discontinuity launched on the ultimate texture fetch coordinates themselves, the derivatives can have big jumps on the tile borders and mipmapping will break aside, creating line artifcats.
One answer to resolve each issues is to pattern the feel with the offset and orientation talked about above at 4 texture tiles, and mix between them when sufficiently near the border of the present tile (within the possitive U and V instructions for instance). Whereas this may launched some quantity of blurring within the sure areas of the tile, it’s acceptable usually, as proven within the picture initially of the article.
After all, for this to work we should use customized texture gradients after all, which should come from the unique repeating UV mapping.
The code is fairly easy, and you’ll find it dwell in Shadertoy: https://www.shadertoy.com/view/lt2GDd
vec4 textureNoTile( sampler2D samp, in vec2 uv )
{
ivec2 iuv = ivec2( flooring( uv ) );
vec2 fuv = fract( uv );
vec4 ofa = hash4( iuv + ivec2(0,0) );
vec4 ofb = hash4( iuv + ivec2(1,0) );
vec4 ofc = hash4( iuv + ivec2(0,1) );
vec4 ofd = hash4( iuv + ivec2(1,1) );
vec2 ddx = dFdx( uv );
vec2 ddy = dFdy( uv );
ofa.zw = signal( ofa.zw-0.5 );
ofb.zw = signal( ofb.zw-0.5 );
ofc.zw = signal( ofc.zw-0.5 );
ofd.zw = signal( ofd.zw-0.5 );
vec2 uva = uv*ofa.zw + ofa.xy, ddxa = ddx*ofa.zw, ddya = ddy*ofa.zw;
vec2 uvb = uv*ofb.zw + ofb.xy, ddxb = ddx*ofb.zw, ddyb = ddy*ofb.zw;
vec2 uvc = uv*ofc.zw + ofc.xy, ddxc = ddx*ofc.zw, ddyc = ddy*ofc.zw;
vec2 uvd = uv*ofd.zw + ofd.xy, ddxd = ddx*ofd.zw, ddyd = ddy*ofd.zw;
vec2 b = smoothstep( 0.25,0.75, fuv );
return combine( combine( textureGrad( samp, uva, ddxa, ddya ),
textureGrad( samp, uvb, ddxb, ddyb ), b.x ),
combine( textureGrad( samp, uvc, ddxc, ddyc ),
textureGrad( samp, uvd, ddxd, ddyd ), b.x), b.y );
}
Word that the code propagates the orientation mirror transformation to the derivatives. For the reason that underlaying {hardware} might be taking absolutely the worth of those, you possibly can fairly savely optimize these away and easily move ddx and ddy to the textureGrad() perform.
The one remaining caveat with this method is that the per-tile hash perform would possibly by alias at excessive minification elements. For instance, if this method is used to texture an enormous terrain, relying on the best way this texturing technique is used, aliasing would possibly happen within the horizon or distant components of the terrain.
Needles to say this method can be utilized not solely with squares, but additionally with any sample that tiles area, akin to triangles or hexagons.
Approach 2
One other solution to get much more natural wanting texture un-tile-fication (simply invented a phrase there) is to bomb the entire floor with randomly scaled, offseted and rotated copies of the unique texture which get blended collectively, with the mixing weight issue dependant on the gap to the middle of every of those copies. This may be completed with a smooth voronoi patter for instance. Mixing weights proportional to a gaussian fallof for every function level within the voronoi sample works fantastic. Simply bear in mind to renormalize the ultimate colour to the full contribution of every function level, in any other case texture brightness vary will probably be misplaced.
Reside code in Shadertoy may be reached right here: https://www.shadertoy.com/view/4tsGzf
vec4 textureNoTile( sampler2D samp, in vec2 uv )
{
vec2 p = flooring( uv );
vec2 f = fract( uv );
vec2 ddx = dFdx( uv );
vec2 ddy = dFdy( uv );
vec4 va = vec4( 0.0 );
float wt = 0.0;
for( int j=-1; j// normalization
return va/wt;
}
After all, the downside is the algorithm samples the feel 9 occasions, which could stress the reminiscence bus an excessive amount of. However within the different hand, it actually assist with top quality imagery or scenario the place simply merely can affort it.
Common texture tiling with GL_REPEAT
Clean Voronoi based mostly tiling
Approach 3
There is a actually low cost solution to obtain this as nicely with a special idea. The concept is to not have tiles like in Approach 1 however areas much like Approach 2, however outlined otherwise. First, let begin by letting the feel repeat over the aircraft as ordinary. Then, think about we’ve got seveal digital variations of this tiling sample, say 8, by merely making use of fixed offsets to the feel lookup. One could make the approach extra highly effective by permitting rotations, symmetries and scales for these 8 digital model, however for our functions offsets suffice many of the occasions. Now, the ultimate un-repeating sample is evaluated at every level of the texuring area by first decide one quantity between 0 and seven, which we are able to name index, after which choosing certainly one of these variations for sampling the texels based mostly on it. By selecting the identical values for the index inside areas, we are able to create patches of the aircraft that use the identical digital sample. After all seams could be seen, so to be able to enhance this we really make the index a floating level worth as an alternative of an integer. That approach the index can change slowly and easily over the aircraft. We are able to then use it to interpolate between the 2 closest digital patterns somewhat than simply choosing one. This low frequency index variation sample may be procedural noise, or random values coming from a Look Up Desk or a texture, which makes it simpler to filter and subsequently get a completelly filterable ensuing sample (not like index values based mostly on a procedural perform which is often tougher to filter).
The code for the approach is under, and a few dwell code in Shadertoy may be discovered right here: https://www.shadertoy.com/view/Xtl3zf
vec4 textureNoTile( sampler2D samp, in vec2 uv )
{
float ok = texture( iChannel1, 0.005*x ).x;
float index = ok*8.0;
float i = flooring( index );
float f = fract( index );
vec2 offa = sin(vec2(3.0,7.0)*(i+0.0));
vec2 offb = sin(vec2(3.0,7.0)*(i+1.0));
vec2 dx = dFdx(x), dy = dFdy(x);
vec3 cola = textureGrad( iChannel0, x + offa, dx, dy ).xxx;
vec3 colb = textureGrad( iChannel0, x + offb, dx, dy ).xxx;
float sum( vec3 v ) { return v.x+v.y+v.z; }
return combine( cola, colb, smoothstep(0.2,0.8,f-0.1*sum(cola-colb)) );
}
A number of notes right here: First, supplied the variation sample is low frequency, sampling it’s actually low cost since virtually all of the occasions the information will probably be within the texture cache. Second, the hashes for creating the offsets for the digital patterns may be as subtle as wanted. Third, texture coordinate derivatives must be computed for correct filtering since we’re introducing discontinuities. Forth, the interpolation perform is usually a cubic or linear like on this instance above, and may be enriched with another fancy approach that makes the pictures look good – on this instance case I am utilizing the distinction between the 2 digital patterns to spice up the distinction of the blended areas.
Bellow is a comparability of the common tiling sample and the Approach 3, which is just two texture fetches, along with a break down of the areas through which the completely different digital textures are sampled:
Common texture tiling with GL_REPEAT
Approach 3 in motion
The index used for variation, encoded as colour
Variation 2, masked by index
Variation 4, masked by index
Variation 6, masked by index