Une implémentation de “shaders” mais sans les capacités du CPU et du GLSL. Le code ne génère qu’une seule frame à cause de sa lenteur d’exécution. Pour créer votre propre image, modifiez la fonction shade() qui s’exécute pour tout les pixels de l’écran. Les vecteurs sont représentés par des listes de 2, 3, ou 4 éléments. Vous pouvez tester les 3 exemples de fonction shade() en commentant ou en utilisant des string multi-lignes pour les autre fonctions shade() que vous n’utilisez pas.
from math import * from kandinsky import * res = (320, 222) def length(u): return sqrt(sum(x**2 for x in u)) def dist(u, v): return sqrt(sum((ux-vx)**2.0 for ux, vx in zip(u, v))) def add(u, n): return [ux+n for ux in u] def add_v(u, v): return [ux+vx for ux, vx in zip(u, v)] def mult(u, n): return [ux*n for ux in u] def mult_v(u, v): return [ux*vx for ux, vx in zip(u, v)] def dot(u, v): return sum(ux*vx for ux, vx in zip(u, v)) def fract(x): return x-floor(x) def fract_v(u): return [ux-floor(ux) for ux in u] def clamp(x, minv, maxv): return min(max(x, minv), maxv) def clamp_v(u, minv, maxv): return [min(max(ux, minv), maxv) for ux in u] def step(edge, x): return 1.0 if x >= edge else 0.0 def mix(x, y, a): return x * (1 - a) + y * a def mix_v(u, v, a): return [mix(ux, uv, a) for ux, uv in zip(u, v)] def abs_v(u): return [abs(x) for x in u] s2 = 1.41421356237 def sierpinski(p): p = fract_v(p) d = 1 inside = 1 for i in range(10): d1 = (p[0] + p[1] - 1)/s2 d2 = 1 - p[0] d3 = 1 - p[1] dTri = max(min(d1, min(d2,d3)),0) r = max(1-dTri*(5-i/2), 0)*(1-i/200) d *= inside *(r**3) + (1-inside) inside *= step(p[0]+p[1], 1) p = mult(p, 2) p = fract_v(p) return d def shade(uv): d = mix(sierpinski(mult(uv, 0.5)), sierpinski(uv), 1) return [d**5, d, sqrt(d), 1.] green = (0.5098, 0.5804, 0.251) purpl = (0.3423,0.0,0.5725) pinkA = (0.9333, 0.5255, 0.8118) pinkB = (0.7412, 0.0353, 0.6471) def shade(uv): color = [0, 0, 0] pinks = [0, 0, 0] pos = add_v((0.5, 0.5), (-uv[0], -uv[1])) angle = atan2(pos[1], pos[0]) rad = length(pos)*2 timer = sin(1) freax = cos(angle*6) color = mix_v(green, purpl, timer) pinks = mix_v(pinkA, pinkB, timer) col = mult(mult(pinks, 1/(rad+0.0001)), 0.661) col = abs_v(col) col = add_v(col, (-tan(color[0]), -tan(color[1]), -tan(color[2]))) fc = [col[0], col[1], col[2]] return fc def shade(uv): fc = [0,0,0] c = dist(uv, (0.5,0.5)) fc[1] = c*pi*1.5 fc[2] = c*pi*3 mult(fc, 1/5) if fc[0] > 1: fc[0] = fc[0] % 1 if fc[1] > 1: fc[1] = fc[1] % 1 if fc[2] > 1: fc[2] = fc[2] % 1 return fc for x in range(res[0]): for y in range(res[1]): uv = [x/res[0], y/res[1]] c = shade(uv) c = (c[0]*255, c[1]*255, c[2]*255) c = clamp_v(c, 0, 255) set_pixel(x, y, c)