Skip to content

Instantly share code, notes, and snippets.

@vjeranc
Last active December 17, 2023 06:08
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vjeranc/265db912d4004c7c0b0f16ae5fdad327 to your computer and use it in GitHub Desktop.
Save vjeranc/265db912d4004c7c0b0f16ae5fdad327 to your computer and use it in GitHub Desktop.
Fragment shader tiling the Las Vegas sphere in Penrose https://whenistheweekend.com/theSphere.html
#define phi 1.61803398874989484820
#define h 1.53884176858762670128
uniform float time;
varying vec2 vUv;
varying vec3 vNormal;
float cx(in vec2 a, in vec2 b) {
return a.x * b.y - a.y * b.x;
}
float signd(in vec2 p1, in vec2 p2, in vec2 p3) {
return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}
bool inTri(in vec2 x, in vec2 A, in vec2 B, in vec2 C) {
float d1 = signd(x, A, B);
float d2 = signd(x, B, C);
float d3 = signd(x, C, A);
bool has_neg = d1 < 0. || d2 < 0. || d3 < 0.;
bool has_pos = d1 > 0. || d2 > 0. || d3 > 0.;
return !(has_neg && has_pos);
}
void main() {
vec2 st = (vUv.xy * h/(1.+0.5*cos(time)) + time/100. + 1.); // zooming action
// vec2 st = (vUv.xy * h + 1.); // static
const int level = 14;
int type = 0; // starting triangle
float X = 4.;
vec2 A = vec2(0.5, h) * X;
vec2 B = vec2(0.) * X;
vec2 C = vec2(1., 0.) * X;
if (cx(B - A, B - st) > 0.) {
gl_FragColor = vec4(0.);
return;
}
if (cx(A - C, A - st) > 0.) {
gl_FragColor = vec4(0.);
return;
}
for (int i = 0; i < level; ++i) {
if (type == 0) { // we are in narrow triangle
vec2 P = A + (B - A) / phi;
// float r = cx(P-C, P-st);
if (inTri(st, P, C, A)) {
B = C;
C = A;
A = P;
type = 1;
} else {
A = C;
C = B;
B = P;
type = 0;
}
} else { // we are in wide triangle
vec2 Q = B + (A - B) / phi;
vec2 R = B + (C - B) / phi;
// float qr = cx(Q - R, Q - st);
// float ar = cx(A - R, A - st);
if (inTri(st, R, C, A)) {
B = C;
C = A;
A = R;
type = 1;
} else if (inTri(st, R, Q, A)) {
C = A;
A = R;
B = Q;
type = 0;
} else {
A = Q;
C = B;
B = R;
type = 1;
}
}
}
float m = 7.1;
vec3 color = type == 1 ? vec3(0.825, 0.294, 0.675) : vec3(0.889, 0.995, 0.337);
color = mix(color, vec3(0.), smoothstep(0.1 * m, 0.8 * m, cx(B - A, st) / length(B - A)));
color = mix(color, vec3(0.), smoothstep(0.1 * m, 0.8 * m, cx(C - A, st) / length(B - A)));
gl_FragColor = vec4(color, 1.);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment