module lx.patterns; function checker (vec2 uv) -> float { vec2 t = abs( fract(uv) ); ivec2 s = floor(t * 2); return floor(s[0] + s[1]) % 2; } function spot (vec2 uv) -> float { // // Parameters // float r = .4; // Find the x and y distance from the center of the tile. // // (It is a signed distance, but this does not matter as the // length will square each component.) // vec2 s = vec2(.5,.5) - fract(uv); return (lengthSqrd(s) < r * r) ? 1 : 0; } function stripe (vec2 uv) -> float { float r = .30; float s = abs(.5 - fract(uv[0])); return (s < r) ? 1 : 0; } function tile (vec2 uv) -> float { float r = .45; vec2 s = abs(vec2(.5,.5) - fract(uv)); return (s[0] < r && s[1] < r) ? 1 : 0; } function diamond (vec2 uv) -> float { float r = .4; float t = abs( vec2(.5, .5) - fract(uv) ); return (t[0] + t[1] <= r) ? 1 : 0; } function wave (vec2 uv) -> float { // // The wave pattern is a variation of the stripe pattern where // the u coordinate is shifted according to sin curve along the // v access. // uv = fract(uv); uv[0] += .15 * sin(2 * uv[1] * PI); uv[0] = abs(.5 - uv[0]); return (uv[0] < .25) ? 1 : 0; } function circle (vec2 uv) -> float { // // Parameters // float r1 = .4; float r2 = .3; vec2 s = vec2(.5,.5) - fract(uv); float r = lengthSqrd(s); return (r < r1 * r1 && r > r2 * r2) ? 1 : 0; } function roundedTile (vec2 uv) -> float { vec2 s = vec2(.5,.5) - fract(uv); float c = (lengthSqrd(s) < .25) ? 1 : 0; return tile(uv) * c; } function ribbon (vec2 uv) -> float { uv = fract(uv); uv[1] += .15 * sin(2 * uv[0] * PI); uv = abs(vec2(.5, .5) - uv); float r = (uv[0] + .1) * .15; return (uv[1] < r) ? 0 : 1; } function spotwave (vec2 uv) -> float { return spot(uv) * wave(uv + vec2(.5, .5)); } function spotdiamondxor (vec2 uv) -> float { float t = spot(uv * 2) + diamond(uv); return (t != 1) ? 1 : 0; } function star(vec2 uv) -> float { uv = abs( vec2(.5,.5) - fract(uv) ); uv = log(E * abs(uv + vec2(.5,.5))); float r = .52; return (uv[0] * uv[1] > r * r) ? 0 : 1; } function checkerSmooth(vec2 uv) -> float { uv = abs( vec2(.5,.5) - fract(uv) ) + vec2(.5, .5); uv[0] = pow(uv[0], .7); uv[1] = pow(uv[1], 1.5); return (uv[0] * uv[1] > .65 * cos(uv[0])) ? 0 : 1; } function gateLattice (vec2 uv) -> float { vec2 t = abs( vec2(.5, .5) - fract(uv) ); float a = t[1] * PI; float x = t[0] * cos(a) - t[1] * sin(a); float y = t[1] * cos(a) + t[0] * sin(a); return abs(x + y) < .1; } function gridBump(vec2 uv) -> float { return tile(uv + vec2(.5, .5)) || spot(uv * 8); } function weave(vec2 uv) -> float { uv = 2 * uv; // Extract the fractional and integer parts vec2 f = fract(uv); vec2 i = uv - f; // Switch the fractional part to a distance // from the tile center f = abs(vec2(.5, .5) - f); // Create a smooth curve from .5 to 1.0 vec2 d = vec2(.5,.5) + pow(cos(f * PI), .75) / 2.0; // Invert the over/under on every other tile float parity = (i[0] + i[1]) % 2; float j0 = (parity > 0) ? 1 : 0; float j1 = 1 - j0; // Invert the color of the lower strip // TODO: Make index aliases until LxLang supports lvalues with expressions as indices float d0 = d[j0]; float d1 = d[j1]; float f0 = f[j0]; float f1 = f[j1]; d0 = 1 - d0; return (f0 < .4) ? d1 : ((f1 < .4) ? d0 : 0); } function circlepattern (vec2 uv) -> float { vec2 f = vec2(.5,.5) - fract(uv); // Normalize angle to 0 to 1 float a = (atan(f[1], f[0]) + PI) / (4 * PI); float r = fract( length(f) * 6 ); float r1 = .35; float r2 = .65; return (r > r1 && r < r2) ? 1 : 0; } function mirrortau (vec2 uv) -> float { vec2 f = vec2(.5,.5) - fract(uv); f = vec2(.5, .5) - fract(abs(f) * 2); // Normalize angle to 0 to 1 float a = (atan(f[1], f[0]) + PI) / (4 * PI); float r = fract( length(2 * f) * (a - .1) * 4); float r1 = .35; float r2 = .65; return (r > r1 && r < r2) ? 1 : 0; } function fatlattice (vec2 uv) -> float { vec2 f = vec2(.5,.5) - fract(uv); f = vec2(.5, .5) - fract(abs(f) * 2); // Normalize angle to 0 to 1 float a = (atan(f[1], f[0]) + PI) / (4 * PI); float r = fract( length(2 * f) * (a - .5) * 4) * .75; float r1 = .35; float r2 = .65; return (r > r1 && r < r2) ? 1 : 0; }