Pixel-Composer/shaders/sh_texture_repeat/sh_texture_repeat.fsh
2024-06-13 17:28:02 +07:00

103 lines
3.1 KiB
GLSL

// Tiling algorithms
// Copyright © 2015 Inigo Quilez
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform vec2 dimension;
uniform vec2 surfaceDimension;
uniform sampler2D surface;
uniform int type;
uniform float seed;
vec4 hash4( vec2 p ) { return fract(sin(vec4( 1.0 + seed + dot(p, vec2(37.0, 17.0)),
2.0 + seed + dot(p, vec2(11.0, 47.0)),
3.0 + seed + dot(p, vec2(41.0, 29.0)),
4.0 + seed + dot(p, vec2(23.0, 31.0)))) * 103.0); }
vec4 randomSample( in vec2 uv ) {
vec2 iuv = floor( uv );
vec2 fuv = fract( uv );
vec4 ofa = hash4( iuv + vec2(0.0, 0.0) );
vec4 ofb = hash4( iuv + vec2(1.0, 0.0) );
vec4 ofc = hash4( iuv + vec2(0.0, 1.0) );
vec4 ofd = hash4( iuv + vec2(1.0, 1.0) );
// transform per-tile uvs
ofa.zw = vec2(sign(ofa.zw - 0.5));
ofb.zw = vec2(sign(ofb.zw - 0.5));
ofc.zw = vec2(sign(ofc.zw - 0.5));
ofd.zw = vec2(sign(ofd.zw - 0.5));
// uv's, and derivarives (for correct mipmapping)
vec2 uva = uv * ofa.zw + ofa.xy;
vec2 uvb = uv * ofb.zw + ofb.xy;
vec2 uvc = uv * ofc.zw + ofc.xy;
vec2 uvd = uv * ofd.zw + ofd.xy;
// fetch and blend
vec2 b = smoothstep(0.25, 0.75, fuv);
return mix( mix( texture2D( surface, fract(uva) ),
texture2D( surface, fract(uvb) ), b.x ),
mix( texture2D( surface, fract(uvc) ),
texture2D( surface, fract(uvd) ), b.x), b.y );
}
vec3 cellSample( in vec2 uv, float v ) {
vec2 p = floor( uv );
vec2 f = fract( uv );
vec3 va = vec3(0.0);
float w1 = 0.0;
float w2 = 0.0;
for( int j=-1; j<=1; j++ )
for( int i=-1; i<=1; i++ ) {
vec2 g = vec2( float(i), float(j) );
vec4 o = hash4( p + g );
vec2 r = g - f + o.xy;
float d = dot(r, r);
float w = exp(-5.0 * d );
vec3 c = texture2D( surface, fract(uv + v * o.zw) ).xyz;
va += w * c;
w1 += w;
w2 += w * w;
}
return va / w1;
}
float sum( vec3 v ) { return v.x + v.y + v.z; }
vec3 onionSample( in vec2 x, float v ) {
float k = hash4( x * 0.005 ).x;
float l = k * 8.0;
float f = fract(l);
float ia = floor(l); // my method
float ib = ia + 1.0;
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
vec3 cola = texture2D( surface, fract(x + v * offa) ).xyz;
vec3 colb = texture2D( surface, fract(x + v * offb) ).xyz;
return mix( cola, colb, smoothstep(0.2, 0.8, f - 0.1 * sum(cola - colb)) );
}
void main() {
vec2 surfRat = dimension / surfaceDimension;
vec2 posRat = v_vTexcoord * surfRat;
if(type == 0) gl_FragColor = texture2D( surface, fract(posRat) );
else if(type == 1) gl_FragColor = randomSample( posRat );
else if(type == 2) gl_FragColor = vec4(cellSample( posRat, 4. ), 1.);
else if(type == 3) gl_FragColor = vec4(onionSample( posRat, 4. ), 1.);
}