lygia
/v1.1.6
/sample
/untile
)Avoiding texture repetition by using Voronoise: a small texture can be used to generate infinite variety instead of tiled repetition. More info: https://iquilezles.org/articles/texturerepetition/
Dependencies:
lygia
/v1.1.6
/math
/const
.glsl
lygia
/v1.1.6
/math
/sum
.glsl
lygia
/v1.1.6
/generative
/random
.glsl
lygia
/v1.1.6
/sample
.glsl
Use:
sampleUNTILE(<SAMPLER_TYPE> texture, <vec2> st, <float> noTiling)
#ifndef SAMPLEUNTILE_TYPE
#define SAMPLEUNTILE_TYPE vec4
#endif
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif
#ifndef SAMPLEUNTILE_SAMPLER_FNC
#if defined(PLATFORM_WEBGL) && __VERSION__ >= 300 && defined(GL_OES_standard_derivatives)
#define SAMPLEUNTILE_SAMPLER_FNC(TEX, UV) textureGrad(TEX, UV, ddx, ddy)
#else
#define SAMPLEUNTILE_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)
#endif
#endif
#ifndef SAMPLEUNTILE_RANDOM_FNC
#define SAMPLEUNTILE_RANDOM_FNC(XYZ) random4(XYZ)
#endif
#ifndef FNC_SAMPLEUNTILE
#define FNC_SAMPLEUNTILE
SAMPLEUNTILE_TYPE sampleUntile(SAMPLER_TYPE tex, in vec2 st) {
#if defined(PLATFORM_WEBGL) && __VERSION__ >= 300 && defined(GL_OES_standard_derivatives)
vec2 ddx = dFdx( st );
vec2 ddy = dFdy( st );
#endif
#ifdef SAMPLEUNTILE_FAST
float k = SAMPLEUNTILE_SAMPLER_FNC(tex, 0.005*st ).x; // cheap (cache friendly) lookup
float l = k*8.0;
float f = fract(l);
#if 0
float ia = floor(l); // IQ method
float ib = ia + 1.0;
#else
float ia = floor(l+0.5); // suslik's method
float ib = floor(l);
f = min(f, 1.0-f)*2.0;
#endif
vec2 offa = sin(vec2(3.0,7.0) * ia); // can replace with any other hash
vec2 offb = sin(vec2(3.0,7.0) * ib); // can replace with any other hash
SAMPLEUNTILE_TYPE cola = SAMPLEUNTILE_SAMPLER_FNC(tex, st + offa );
SAMPLEUNTILE_TYPE colb = SAMPLEUNTILE_SAMPLER_FNC(tex, st + offb );
return mix( cola, colb, smoothstep(0.2, 0.8, f - 0.1 * sum(cola-colb) ) );
#else
// More expensive because it samples x9
//
vec2 p = floor( st );
vec2 f = fract( st );
SAMPLEUNTILE_TYPE va = SAMPLEUNTILE_TYPE(0.0);
float w1 = 0.0;
float w2 = 0.0;
for( float y = -1.0; y <= 1.0; y++ )
for( float x = -1.0; x <= 1.0; x++ ) {
vec2 g = vec2(x, y);
vec4 o = SAMPLEUNTILE_RANDOM_FNC( p + g );
vec2 r = g - f + o.xy;
float d = dot(r,r);
float w = exp(-5.0*d );
SAMPLEUNTILE_TYPE c = SAMPLEUNTILE_SAMPLER_FNC(tex, st + o.zw);
va += w*c;
w1 += w;
w2 += w*w;
}
// normal averaging --> lowers contrasts
// return va/w1;
// contrast preserving average
float mean = 0.3;
SAMPLEUNTILE_TYPE res = mean + (va-w1*mean)/sqrt(w2);
return res;
#endif
}
#endif
Dependencies:
Use:
sampleUNTILE(<SAMPLER_TYPE> texture, <float2> st, <float> noTiling)
#ifndef SAMPLEUNTILE_TYPE
#define SAMPLEUNTILE_TYPE float4
#endif
#ifndef SAMPLEUNTILE_SAMPLER_FNC
#define SAMPLEUNTILE_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV)
#endif
#ifndef SAMPLEUNTILE_RANDOM_FNC
#define SAMPLEUNTILE_RANDOM_FNC(XYZ) random4(XYZ)
#endif
#ifndef FNC_SAMPLEUNTILE
#define FNC_SAMPLEUNTILE
SAMPLEUNTILE_TYPE sampleUntile(SAMPLER_TYPE tex, in float2 st, float v) {
float2 p = floor( st );
float2 f = frac( st );
// derivatives (for correct mipmapping)
// float2 ddx = dFdx( st );
// float2 ddy = dFdy( st );
SAMPLEUNTILE_TYPE va = float4(0.0, 0.0, 0.0, 0.0);
float w1 = 0.0;
float w2 = 0.0;
float2 g = float2(-1.0, -1.0);
for( g.y = -1.0; g.y <= 1.0; g.y++ )
for( g.x = -1.0; g.x <= 1.0; g.x++ ) {
float4 o = SAMPLEUNTILE_RANDOM_FNC( p + g );
float2 r = g - f + o.xy;
float d = dot(r,r);
float w = exp(-5.0*d );
// SAMPLEUNTILE_TYPE c = textureGrad(tex, st + v*o.zw, ddx, ddy );
SAMPLEUNTILE_TYPE c = SAMPLEUNTILE_SAMPLER_FNC(tex, st + v*o.zw);
va += w*c;
w1 += w;
w2 += w*w;
}
// normal averaging --> lowers contrasts
// return va/w1;
// contrast preserving average
float mean = 0.3;// textureGrad( samp, uv, ddx*16.0, ddy*16.0 ).x;
SAMPLEUNTILE_TYPE res = mean + (va-w1*mean)/sqrt(w2);
return lerp( va/w1, res, v );
}
#endif
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository