Skip to content

Instantly share code, notes, and snippets.

@thobbs
Created March 4, 2022 19:37
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save thobbs/8b5e1b9ce92d1c0cb937ad59ebd21eaf to your computer and use it in GitHub Desktop.
Save thobbs/8b5e1b9ce92d1c0cb937ad59ebd21eaf to your computer and use it in GitHub Desktop.
Source Code for Wall (2022)
(defn adjust-flow-points
[flow-points disturbance-x disturbance-y disturbance-radius disturbance-theta]
(for [[x y theta] flow-points]
(let [disturbance-dist (q/dist disturbance-x disturbance-y x y)
theta-adjust (if (> disturbance-dist disturbance-radius)
0
(rescale disturbance-dist 0 disturbance-radius disturbance-theta 0))
; final-theta (min (pi 0.72) (max (pi 0.45) (+ theta theta-adjust)))
final-theta (+ theta theta-adjust)]
[x y final-theta])))
(defn get-flow-points
[default-theta spacing left-x right-x top-y bot-y]
(let [flow-points (for [y (range top-y bot-y spacing)
x (range left-x right-x spacing)]
[x y default-theta])]
(loop [n 30
flow-points flow-points]
(if (zero? n)
(vec flow-points)
(let [disturbance-x (q/random left-x right-x)
disturbance-y (q/random top-y bot-y)
disturbance-theta (gauss 0 (pi 0.0095))
disturbance-radius (max (w 0.1) (abs-gauss (w 0.60) (w 0.25)))
adjusted (adjust-flow-points flow-points
disturbance-x disturbance-y
disturbance-radius disturbance-theta)]
(recur (dec n) adjusted))))))
(defn draw-dirty-dot
[x y radius skew? skew-mean-theta]
(let [starting-theta (q/random 0 (pi 2.0))
skew-theta (mod (gauss skew-mean-theta (pi 0.2)) (pi 1.0))
skew-ratio (if skew?
(gauss 0.0 0.6)
0)]
(q/begin-shape)
(loop [theta starting-theta]
(if (> theta (+ starting-theta (pi 2.0)))
(apply q/curve-vertex (angular-coords x y starting-theta radius))
(let [angle-dist (mod (q/abs (- theta skew-theta)) (pi 1.0))
skew-modifier (rescale angle-dist 0.0 (pi 1.0) (+ 1.0 skew-ratio) (- 1.0 skew-ratio))
noisy-radius (if (= starting-theta theta)
radius
(gauss radius (* radius 0.15)))
exact-radius (* noisy-radius skew-modifier)]
(apply q/curve-vertex (angular-coords x y theta exact-radius))
(recur (+ theta (abs-gauss (pi 0.1) (pi 0.02)))))))
(q/end-shape :close)))
(defn fill-brick
[y overlay-graphics & [vertical?]]
(let [hue (mod (rescale y 0 (h) 220 385) 360)
; dimmer close to ground
ground-d (Math/pow (/ (- (h) y) (h)) 2)
bright-adjust (min 0.0
(max -2.0 (rescale ground-d
0 0.03
0.0 0)))
; slightly dimmer close to top
top-d (Math/pow (/ y (h)) 2)
bright-adjust-2 (min 0.0
(max -2.7 (rescale top-d
0 0.07
-2.3 0)))
sat-adjust (max 0 (rescale ground-d
0 0.03
2.0 0))
sat-adjust-2 (min 0.0
(max -1.0 (rescale top-d
0 0.05
-1.0 0)))
mid-bright (gauss (+ 87 bright-adjust bright-adjust-2) 0.5)
step (case detail-level
:low (w 0.005)
:med (w 0.001)
:high (w 0.0002))
rect-len (* step 1.5)
x-noise-scale (max (w 0.005) (gauss (w 0.014) (w 0.001)))
y-noise-scale (max (w 0.005) (gauss (w 0.014) (w 0.001)))
noise-offset (q/random 0 (w 25.0))]
(q/with-graphics overlay-graphics
(q/background hue (+ 0.5 sat-adjust sat-adjust-2) mid-bright)
(q/no-stroke)
(let [x-end (if vertical? (h 0.031) (w 0.0501))
y-end (if vertical? (w 0.0501) (h 0.031))]
(doseq [x1 (range 0 x-end step)
y1 (range 0 y-end step)]
(let [[x2 y2] (angular-coords x1 y1 (pi -0.23) (w 0.001))
n1 (q/noise (/ (+ x1 noise-offset) x-noise-scale) (/ y1 y-noise-scale))
n2 (q/noise (/ (+ x2 noise-offset) x-noise-scale) (/ y2 y-noise-scale))
height-diff (- n1 n2)
light-bright-adjust (if (< height-diff 0)
(* -1.0 (Math/pow (rescale height-diff 0.0 -1.0 0.0 40.0) 1.65))
(* 1.0 (Math/pow (rescale height-diff 0.0 1.0 0.0 30.0) 1.65)))
light-bright-adjust (min 6 (max -20 light-bright-adjust))
final-bright (gauss
(min 97
(+ mid-bright light-bright-adjust))
0.6)]
(q/fill hue (+ 0.5 sat-adjust sat-adjust-2) final-bright)
(q/rect x1 y1 rect-len rect-len)))))))
(defn drop-curve-before-intersection-with-line
[curve p1 p2]
(loop [curve curve]
(if (< (count curve) 2)
nil
(let [[seg-start seg-end] (take 2 curve)
inter (lines-intersection-point
p1 p2
seg-start seg-end)]
(if inter
(concat [inter] (rest curve))
(recur (rest curve)))))))
(defn draw-brick
[x y
brick-width brick-height
grout-horizontal grout-vertical
overlay-graphics mask-graphics shadow-mask-graphics
get-offset]
(let [[brick-shift-x brick-shift-y] (get-offset x y)
mask-offset (w 0.005)
[top-right-x-off top-right-y-off] (get-offset (+ x brick-width) y)
ang (angle brick-shift-x brick-shift-y (+ brick-width top-right-x-off) top-right-y-off)
rotation (gauss ang (pi 0.0015))
y-shift (gauss brick-shift-y (w 0.00004))
x-shift (gauss brick-shift-x (w 0.00004))
x (+ x x-shift)
y (+ y y-shift)
top-left-x mask-offset
top-left-y mask-offset
top-right (angular-coords top-left-x top-left-y rotation brick-width)
bot-left (angular-coords top-left-x top-left-y (+ rotation (pi 0.5)) brick-height)
bot-right (angular-coords (first bot-left) (second bot-left) rotation brick-width)
curve-variance (w 0.000045)
top-curve (concat
(let [t (gauss 0.0 0.005)
x (interpolate top-left-x (first top-right) t)
y (interpolate top-left-y (second top-right) t)]
[[x y]])
(for [t (range 0.1 0.91 0.1)]
(let [final-t (gauss t 0.02)
x (interpolate top-left-x (first top-right) final-t)
y (interpolate top-left-y (second top-right) final-t)]
[x (gauss y curve-variance)]))
(let [t (gauss 1.0 0.005)
x (interpolate top-left-x (first top-right) t)
y (interpolate top-left-y (second top-right) t)]
[[x y]]))
right-curve (concat
(for [t (range 0.2 0.81 0.2)]
(let [final-t (gauss t 0.03)
x (interpolate (first top-right) (first bot-right) final-t)
y (interpolate (second top-right) (second bot-right) final-t)]
[(gauss x curve-variance) y]))
(let [t (gauss 1.0 0.01)
x (interpolate (first top-right) (first bot-right) t)
y (interpolate (second top-right) (second bot-right) t)]
[[x y]]))
bot-curve (concat
(for [t (range 0.1 0.91 0.1)]
(let [final-t (gauss t 0.02)
x (interpolate (first bot-right) (first bot-left) final-t)
y (interpolate (second bot-right) (second bot-left) final-t)]
[x (gauss y curve-variance)]))
(let [t (gauss 1.0 0.005)
x (interpolate (first bot-right) (first bot-left) t)
y (interpolate (second bot-right) (second bot-left) t)]
[[x y]]))
left-curve (for [t (range 0.2 0.81 0.2)]
(let [final-t (gauss t 0.03)
x (interpolate (first bot-left) top-left-x final-t)
y (interpolate (second bot-left) top-left-y final-t)]
[(gauss x curve-variance) y]))]
(q/with-graphics mask-graphics
(q/background 0 0 0)
(q/begin-shape)
(doseq [[x y] (concat top-curve right-curve bot-curve left-curve)]
(q/vertex x y))
(q/end-shape :close))
(fill-brick y overlay-graphics false)
(.mask overlay-graphics mask-graphics)
(q/image overlay-graphics
(- x mask-offset) (- y mask-offset)
(+ brick-width grout-vertical (w 0.01))
(+ brick-height grout-horizontal (w 0.01)))
(q/stroke-cap :square)
; top highlight
(q/stroke 40 0 100 (max 0 (gauss 0.2 0.1)))
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.0001))))
(q/no-fill)
(q/begin-shape)
(doseq [[inner-x inner-y] top-curve]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x (+ final-y (w 0.0003)))))
(q/end-shape)
; right highlight
(q/stroke 40 0 100 (max 0 (gauss 0.35 0.05)))
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0007) (w 0.00015))))
(q/begin-shape)
(doseq [[inner-x inner-y] (concat (take-last 1 top-curve) right-curve)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex (- final-x (w 0.0003)) final-y)))
(q/end-shape)
; cast shadow
(q/with-graphics shadow-mask-graphics
(let [shadow-thick (max 0 (gauss (w 0.0018) (w 0.0006)))
noise-offset (q/random 0 (w 200.0))
bot-points (concat (take-last 1 right-curve) bot-curve)
bot-points-and-thicknesses (for [[x y] bot-points]
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03)))
n (rescale n 0.0 1.0 -0.25 1.0)
thick (max 0 (* n shadow-thick))]
[[x y] thick]))
left-points (concat left-curve (take 1 top-curve))
left-points-and-thicknesses (for [[x y] left-points]
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03)))
n (rescale n 0.0 1.0 -0.35 1.0)
thick (max 0 (* n shadow-thick))]
[[x y] thick]))
shadow-left-full (for [[[x y] thick] (reverse left-points-and-thicknesses)]
(angular-coords x y (pi 0.85) thick))
shadow-left-shrunk (for [[[x y] thick] (reverse left-points-and-thicknesses)]
(angular-coords x y (pi 0.85) (* thick 0.6)))
shadow-bot-full (for [[[x y] thick] (reverse bot-points-and-thicknesses)]
(angular-coords x y (pi 0.85) thick))
shadow-bot-shrunk (for [[[x y] thick] (reverse bot-points-and-thicknesses)]
(angular-coords x y (pi 0.85) (* thick 0.6)))]
(q/no-stroke)
; outer softer edge of shadow
(q/fill 0 0 40)
(q/begin-shape)
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-full shadow-bot-full)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x final-y)))
(q/end-shape :close)
; inner deep shadow
(q/fill 0 0 65)
(q/begin-shape)
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-shrunk shadow-bot-shrunk)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x final-y)))
(q/end-shape :close)))
; does the brick sit in the cast shadow?
(when (and (< x (w 0.4185))
(> (+ x brick-width) (w 0.4195)))
(let [p1 [(w 0.4187) (- y (h 0.005))]
p2 [(w 0.4187) (+ y brick-height (h 0.005))]
finalized-top (for [[inner-x inner-y] top-curve]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
[final-x final-y]))
finalized-right (for [[inner-x inner-y] right-curve]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
[final-x final-y]))
finalized-bottom (for [[inner-x inner-y] bot-curve]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
[final-x final-y]))
trimmed-top (drop-curve-before-intersection-with-line finalized-top p1 p2)
trimmed-bot (reverse
(drop-curve-before-intersection-with-line
(reverse finalized-bottom)
p1 p2))
base-x-offset (abs-gauss 0 (w 0.0005))
noise-y-offset (q/random 0 (h 4.0))
y-noise-scale (h 0.025)]
(when (not (seq trimmed-top))
(println "no trimmed top"))
(when (not (seq trimmed-bot))
(println "no trimmed bot"))
(when (and (seq trimmed-top)
(seq trimmed-bot))
(q/with-graphics shadow-mask-graphics
(q/fill 0 0 0)
(q/begin-shape)
(doseq [[inner-x inner-y] (concat top-curve right-curve bot-curve left-curve)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x final-y)))
(q/end-shape :close)
(q/stroke-weight (w 0.0004))
; outer soft shadow
(q/fill 0 0 50)
(q/stroke 0 0 50)
(q/begin-shape)
(doseq [p (concat (drop 2 trimmed-top) finalized-right (drop-last 2 trimmed-bot))]
(apply q/vertex p))
(let [[top-x top-y] (first trimmed-top)
[bot-x bot-y] (last trimmed-bot)]
(doseq [t (range 0.0 1.01 0.05)]
(let [x (interpolate bot-x top-x t)
y (interpolate bot-y top-y t)
n (q/noise (/ (+ y noise-y-offset) y-noise-scale))
x-offset (rescale n 0.0 1.0 0 (w 0.0015))]
(q/vertex (+ x x-offset base-x-offset (w -0.0003)) y))))
(q/end-shape :close)
; inner dark shadow
(q/fill 0 0 75)
(q/stroke 0 0 75)
(q/begin-shape)
(doseq [p (concat (drop 2 trimmed-top) finalized-right (drop-last 2 trimmed-bot))]
(apply q/vertex p))
(let [[top-x top-y] (first trimmed-top)
[bot-x bot-y] (last trimmed-bot)]
(doseq [t (range 0.0 1.01 0.05)]
(let [x (interpolate bot-x top-x t)
y (interpolate bot-y top-y t)
n (q/noise (/ (+ y noise-y-offset) y-noise-scale))
x-offset (rescale n 0.0 1.0 0 (w 0.0015))]
(q/vertex (+ x x-offset base-x-offset (w 0.0002)) y))))
(q/end-shape :close)
(q/no-stroke)))))))
(defn draw-brick-vertical
[x y brick-width brick-height
grout-horizontal grout-vertical
overlay-graphics mask-graphics shadow-mask-graphics]
(let [mask-offset (w 0.005)
rotation (gauss 0 (pi 0.0017))
y-shift (gauss 0 (w 0.00004))
x-shift (gauss 0 (w 0.00004))
x (+ x x-shift)
y (+ y y-shift)
top-left-x mask-offset
top-left-y mask-offset
top-right (angular-coords top-left-x top-left-y rotation brick-width)
bot-left (angular-coords top-left-x top-left-y (+ rotation (pi 0.5)) brick-height)
bot-right (angular-coords (first bot-left) (second bot-left) rotation brick-width)
curve-variance (w 0.000045)
top-curve (concat
(let [t (gauss 0.0 0.01)
x (interpolate top-left-x (first top-right) t)
y (interpolate top-left-y (second top-right) t)]
[[x y]])
(for [t (range 0.2 0.81 0.2)]
(let [final-t (gauss t 0.03)
x (interpolate top-left-x (first top-right) final-t)
y (interpolate top-left-y (second top-right) final-t)]
[x (gauss y curve-variance)]))
(let [t (gauss 1.0 0.01)
x (interpolate top-left-x (first top-right) t)
y (interpolate top-left-y (second top-right) t)]
[[x y]]))
right-curve (concat
(for [t (range 0.1 0.91 0.1)]
(let [final-t (gauss t 0.02)
x (interpolate (first top-right) (first bot-right) final-t)
y (interpolate (second top-right) (second bot-right) final-t)]
[(gauss x curve-variance) y]))
(let [t (gauss 1.0 0.005)
x (interpolate (first top-right) (first bot-right) t)
y (interpolate (second top-right) (second bot-right) t)]
[[x y]]))
bot-curve (concat
(for [t (range 0.2 0.81 0.2)]
(let [final-t (gauss t 0.03)
x (interpolate (first bot-right) (first bot-left) final-t)
y (interpolate (second bot-right) (second bot-left) final-t)]
[x (gauss y curve-variance)]))
(let [t (gauss 1.0 0.01)
x (interpolate (first bot-right) (first bot-left) t)
y (interpolate (second bot-right) (second bot-left) t)]
[[x y]]))
left-curve (for [t (range 0.1 0.91 0.1)]
(let [final-t (gauss t 0.02)
x (interpolate (first bot-left) top-left-x final-t)
y (interpolate (second bot-left) top-left-y final-t)]
[(gauss x curve-variance) y]))]
(q/with-graphics mask-graphics
(q/background 0 0 0)
(q/begin-shape)
(doseq [[x y] (concat top-curve right-curve bot-curve left-curve)]
(q/vertex x y))
(q/end-shape :close))
(fill-brick y overlay-graphics true)
(.mask overlay-graphics mask-graphics)
(q/image overlay-graphics
(- x mask-offset) (- y mask-offset)
(+ brick-width grout-vertical (w 0.01))
(+ brick-height grout-horizontal (w 0.01)))
(q/stroke-cap :square)
; top highlight
(q/stroke 40 2 100 (max 0 (gauss 0.4 0.1)))
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.00015))))
(q/no-fill)
(q/begin-shape)
(doseq [[inner-x inner-y] top-curve]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x (+ final-y (w 0.0004)))))
(q/end-shape)
; right highlight
(q/stroke 40 2 100 (max 0 (gauss 0.5 0.1)))
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0005) (w 0.00015))))
(q/begin-shape)
(doseq [[inner-x inner-y] (concat (take-last 1 top-curve) right-curve)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex (- final-x (w 0.0004)) final-y)))
(q/end-shape)
; cast shadow
(q/with-graphics shadow-mask-graphics
(let [shadow-thick (max 0 (gauss (w 0.0019) (w 0.0005)))
noise-offset (q/random 0 (w 200.0))
bot-points (concat (take-last 1 right-curve) bot-curve)
bot-points-and-thicknesses (for [[x y] bot-points]
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03)))
n (rescale n 0.0 1.0 -0.1 1.0)
thick (max 0 (* n shadow-thick))]
[[x y] thick]))
left-points (concat left-curve (take 1 top-curve))
left-points-and-thicknesses (for [[x y] left-points]
(let [n (q/noise (/ (+ x noise-offset) (w 0.05)) (/ y (w 0.03)))
n (rescale n 0.0 1.0 -0.4 1.0)
thick (max 0 (* n shadow-thick))]
[[x y] thick]))
shadow-left-full (for [[[x y] thick] (reverse left-points-and-thicknesses)]
(angular-coords x y (pi 0.85) thick))
shadow-left-shrunk (for [[[x y] thick] (reverse left-points-and-thicknesses)]
(angular-coords x y (pi 0.85) (* thick 0.6)))
shadow-bot-full (for [[[x y] thick] (reverse bot-points-and-thicknesses)]
(angular-coords x y (pi 0.85) thick))
shadow-bot-shrunk (for [[[x y] thick] (reverse bot-points-and-thicknesses)]
(angular-coords x y (pi 0.85) (* thick 0.6)))]
(q/no-stroke)
; outer soft edge of shadow
(q/fill 0 0 40)
(q/begin-shape)
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-full shadow-bot-full)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x final-y)))
(q/end-shape :close)
; outer soft edge of shadow
(q/fill 0 0 65)
(q/begin-shape)
(doseq [[inner-x inner-y] (concat bot-points left-points shadow-left-shrunk shadow-bot-shrunk)]
(let [final-x (+ x inner-x (* mask-offset -1.0))
final-y (+ y inner-y (* mask-offset -1.0))]
(q/vertex final-x final-y)))
(q/end-shape :close)))))
(defn color-grout
[full-width]
(q/no-stroke)
(doseq [x (range 0 full-width (w 0.005))
y (range 0 (h 1.02) (w 0.005))]
(let [n (q/noise (/ x (w 0.15)) (/ y (w 0.15)))
mean-bright (if (< y (h 0.5))
(rescale y 0 (h 0.5) 68 56)
(rescale y (h 0.5) (h) 56 60))
bright-adjust (rescale n 0.0 1.0 -19.0 8.0)
ground-d (Math/pow (/ (- (h) y) (h)) 2)
bright-adjust-2 (max 0 (rescale ground-d
0 0.05
6 0))
sat-adjust (max 0 (rescale ground-d
0 0.05
3 0))]
(q/fill 20 sat-adjust (+ mean-bright bright-adjust bright-adjust-2))
(q/rect x y (w 0.011) (w 0.011))))
; big splotches
(let [num-iterations (case detail-level
:low 0
:med 10500
:high 70000)]
(dotimes [_ (* num-iterations (/ full-width (w)))]
(let [x (q/random (w -0.01) (w 1.01))
y (q/random (h -0.01) (h 1.01))
n (q/noise (/ x (w 0.005)) (/ y (w 0.005)))
mean-bright (if (< y (h 0.5))
(rescale y 0 (h 0.5) 68 56)
(rescale y (h 0.5) (h) 56 58))
bright-adjust (rescale n 0.0 1.0 -19.0 8.0)
ground-d (Math/pow (/ (- (h) y) (h)) 2)
bright-adjust-2 (max 0 (rescale ground-d
0 0.05
6 0))
final-bright (gauss (+ mean-bright bright-adjust bright-adjust-2) 2)
sat-adjust (max 0 (rescale ground-d
0 0.05
3 0))
alpha (min 1.0 (gauss 0.5 0.3))
big? true
e-width (if big?
(max (w 0.0005) (gauss (w 0.0025) (w 0.003)))
(max (w 0.0001) (gauss (w 0.0004) (w 0.0002))))
e-height (* e-width (gauss 1.0 0.2))]
(q/fill (gauss 25 2)
(max 0 (gauss sat-adjust 1))
final-bright
alpha)
(if (> e-width (w 0.0004))
(draw-dirty-dot x y (/ e-width 2.0) true 0)
(q/ellipse x y e-width e-height)))))
; small splotches
(let [num-iterations (case detail-level
:low 0
:med 150000
:high 1500000)]
(dotimes [_ (* num-iterations (/ full-width (w)))]
(let [x (q/random (w -0.01) (w 1.01))
y (q/random (h -0.01) (h 1.01))
n (q/noise (/ x (w 0.005)) (/ y (w 0.005)))
mean-bright (if (< y (h 0.5))
(rescale y 0 (h 0.5) 68 56)
(rescale y (h 0.5) (h) 56 58))
bright-adjust (rescale n 0.0 1.0 -19.0 8.0)
ground-d (Math/pow (/ (- (h) y) (h)) 2)
bright-adjust-2 (max 0 (rescale ground-d
0 0.05
6 0))
final-bright (min 96
(max 10
(gauss (+ mean-bright bright-adjust bright-adjust-2) 4)))
sat-adjust (max 0 (rescale ground-d
0 0.05
3 0))
alpha (min 1.0 (gauss 0.5 0.3))
big? false
e-width (if big?
(max (w 0.0005) (gauss (w 0.0025) (w 0.003)))
(max (w 0.0001) (gauss (w 0.0004) (w 0.0002))))
e-height (* e-width (gauss 1.0 0.2))]
(q/fill (gauss 25 2)
(max 0 (gauss sat-adjust 1))
final-bright
alpha)
(if (> e-width (w 0.0004))
(draw-dirty-dot x y (/ e-width 2.0) true 0)
(q/ellipse x y e-width e-height))))))
(defn draw-right-metal-piece-shadow
[x-pos shadow-mask-graphics]
(q/with-graphics shadow-mask-graphics
(q/fill 0 0 75)
(q/no-stroke)
(q/begin-shape)
(q/vertex x-pos 0)
(q/vertex x-pos (h))
(let [noise-offset (q/random 0 (h 100.0))]
(doseq [y (range (h) (h -0.02) (h -0.005))]
(let [n (q/noise (/ (+ y noise-offset) (h 0.025)))
x-offset (rescale n 0.0 1.0 (w -0.002) (w -0.0005))]
(q/vertex (+ x-pos x-offset) y)))
(q/end-shape :close))))
(defn draw-right-metal-piece
[x-pos]
(q/no-stroke)
(doseq [y (range 0 (h) (h 0.005))]
(let [bright (cond
(< y (h 0.55))
(min 99 (rescale y 0 (h 0.55) 105 93))
(< y (h 0.87))
(max 59 (rescale y (h 0.55) (h 0.87) 93 70))
:else
(max 59 (rescale y (h 0.87) (h) 70 81)))
sat (cond
(< y (h 0.55))
(rescale y 0 (h 0.55) 5 8)
(< y (h 0.87))
(rescale y (h 0.55) (h 0.87) 8 7)
:else
(rescale y (h 0.87) (h) 7 3))
highlight-bright (rescale y 0 (h) 99 80)]
; base
(q/fill 220 sat bright)
(q/rect x-pos y (w 0.004) (h 0.006))
(when (between? y (h 0.15) (h 0.153))
(q/fill 220 0 (- bright 12))
(q/rect x-pos y (w 0.004) (h 0.0015)))
; rightmost highlight
(q/fill 220 2 highlight-bright)
(q/rect (+ x-pos (w 0.004)) y (w 0.0004) (h 0.007))
; left mid
(q/fill 220 sat (- bright 8))
(q/rect x-pos y (w 0.001) (h 0.007))
(when (between? y (h 0.15) (h 0.15))
(q/fill 220 0 (- bright 14))
(q/rect x-pos (- y (h 0.001)) (w 0.001) (h 0.0015)))
; left weak highlight
(q/fill 220 2 (- highlight-bright 4))
(q/rect x-pos y (w 0.0003) (h 0.007))
; inner right highlight
(q/fill 220 2 highlight-bright)
(q/rect (+ x-pos (w 0.0008)) y (w 0.0005) (h 0.007)))))
(defn draw-left-metal-piece
[x-pos]
; left metal base
(q/fill 220 3 17)
(q/rect (- x-pos (w 0.004)) 0 (w 0.004) (h 1.01))
(doseq [y (range 0 (h) (h 0.005))]
(let [hue (mod (rescale y 0 (h) 220 410) 360)
sat (max 2 (rescale y 0 (h) -2 19))
bright (rescale y 0 (h) 17 23.5)]
(q/fill hue sat bright)
(q/rect (- x-pos (w 0.004)) y (w 0.004) (h 0.007))))
(doseq [y (range 0 (h) (h 0.005))]
(let [bright (if (< y (h 0.65))
(rescale y 0 (h 0.65) 90 75)
(max 57 (rescale y (h 0.65) (h) 75 53)))
highlight-bright (rescale y 0 (h) 97.5 75)]
; center
(q/fill 220 3 bright)
(q/rect (- x-pos (w 0.0007)) y (w 0.0007) (h 0.007))
; inner right highlight
(q/fill 220 2 highlight-bright)
(q/rect (- x-pos (w 0.0002)) y (w 0.0005) (h 0.007)))))
(defn draw-vent
[]
(q/no-stroke)
; black shadow
(q/fill 0 0 2)
(q/rect 0 0 (w 0.07) (h 0.148))
(let [the-overlay (q/create-graphics (w 0.07) (h 0.15))
the-mask (q/create-graphics (w 0.07) (h 0.15))]
(q/with-graphics the-overlay
(set-color-mode))
(q/with-graphics the-mask
(set-color-mode))
(doseq [y (range (h -0.0073) (h 0.15) (h 0.0237))]
(q/fill 50 1 5)
(q/rect 0 y (w 0.0685) (h 0.011))
; bottom reflection-based highlight
(q/fill 220 2 10)
(doseq [x (range 0 (w 0.0655) (w 0.002))]
(let [bright (max 7 (rescale x 0 (w 0.0735) 19 9))]
(q/fill 50 1 bright)
(q/rect x (+ y (h 0.008)) (w 0.003) (h 0.003))))
(q/fill 220 2 10)
(doseq [x (range 0 (w 0.0655) (w 0.002))]
(let [bright (max 4 (rescale x 0 (w 0.0735) 14 4))]
(q/fill 50 1 bright)
(q/rect x (+ y (h 0.008)) (w 0.003) (h 0.001))))
(q/fill 220 0 2)
(q/rect 0 (+ y (h 0.0047)) (w 0.0685) (h 0.001))
; lower lit portion
(q/with-graphics the-mask
(q/background 0 0 0)
(q/no-stroke)
(let [points [[0 (+ y (h 0.006))]
[(w 0.033) (+ y (h 0.006))]
[(w 0.035) (+ y (h 0.006))]
[(w 0.0375) (+ y (h 0.008))]
[(w 0.0355) (+ y (h 0.008))]
[0 (+ y (h 0.008))]]
smoothed-points (chaikin-curve-retain-ends points 1 0.25)]
(q/fill 0 0 70)
(q/begin-shape)
(doseq [[x y] smoothed-points]
(q/vertex x y))
(q/end-shape :close)
(q/fill 0 0 100)
(q/begin-shape)
(doseq [[x y] smoothed-points]
(q/vertex (- x (w 0.0008)) y))
(q/end-shape :close)))
(q/with-graphics the-overlay
(let [mean-bright (rescale y 0 (h 0.14) 70 78)]
(q/background 50 9 mean-bright)
(q/no-stroke)
(doseq [x (range 0 (w 0.038) (w 0.0002))
y (range (- y (h 0.01)) (+ y (h 0.01)) (w 0.0005))]
(let [n (q/noise (/ x (w 0.002)) (/ y (w 0.002)))
bright-adjust (rescale n 0.0 1.0 -11.0 11.0)
final-bright (+ mean-bright bright-adjust)]
(q/fill 50 7 (gauss final-bright 1))
(q/rect x y (w 0.001) (w 0.001))))))
(.mask the-overlay the-mask)
(q/image the-overlay 0 0)
; upper lit portion
(q/with-graphics the-mask
(q/background 0 0 0)
(q/no-stroke)
(let [points [[0 (+ y (h 0.0013))]
[(w 0.027) (+ y (h 0.0013))]
[(w 0.029) (+ y (h 0.0013))]
[(w 0.033) (+ y (h 0.0045))]
[(w 0.027) (+ y (h 0.0045))]
[0 (+ y (h 0.0045))]]
smoothed-points (chaikin-curve-retain-ends points 1 0.25)]
(q/fill 0 0 70)
(q/begin-shape)
(doseq [[x y] smoothed-points]
(q/vertex x y))
(q/end-shape :close)
(q/fill 0 0 100)
(q/begin-shape)
(doseq [[x y] smoothed-points]
(q/vertex (- x (w 0.0008)) y))
(q/end-shape :close)))
(q/with-graphics the-overlay
(let [mean-bright (rescale y 0 (h 0.14) 58 66)]
(q/background 50 8 mean-bright)
(q/no-stroke)
(doseq [x (range 0 (w 0.035) (w 0.0002))
y (range (- y (h 0.01)) (+ y (h 0.01)) (w 0.0005))]
(let [n (q/noise (/ x (w 0.002)) (/ y (w 0.002)))
bright-adjust (rescale n 0.0 1.0 -17.0 17.0)
final-bright (+ mean-bright bright-adjust)]
(q/fill 50 6 (gauss final-bright 1))
(q/rect x y (w 0.001) (w 0.001))))))
(.mask the-overlay the-mask)
(q/image the-overlay 0 0)))
; lower wide border
(q/fill 220 8 52)
(q/rect 0 (h 0.143) (w 0.0685) (h 0.005))
; highlight on lower wide border
(q/fill 220 8 67)
(q/rect 0 (h 0.143) (w 0.0685) (h 0.0006))
; shadow on lower wide border
(q/fill 220 6 15)
(q/rect (w 0.0634) (h 0.143) (w 0.0051) (h 0.005))
(q/fill 220 8 11)
(q/rect (w 0.0638) (h 0.143) (w 0.0047) (h 0.005))
; right wide border
(q/fill 220 8 11)
(q/rect (w 0.066) 0 (w 0.0025) (h 0.143))
; inner diagonal
(q/stroke 0 0 5)
(q/stroke-weight (w 0.0004))
(q/line (w 0.066) (h 0.143)
(w 0.0685) (h 0.148))
(q/no-stroke)
; center of right border
(q/fill 220 7 54)
(q/rect (w 0.0685) 0 (w 0.001) (h 0.15))
; rightmost highlight
(q/fill 220 4 80)
(q/rect (w 0.0693) 0 (w 0.0007) (h 0.15))
; center of bottom border
(q/fill 220 6 44)
(q/begin-shape)
(q/vertex 0 (h 0.148))
(q/vertex (w 0.0685) (h 0.148))
(q/vertex (w 0.0697) (+ (h 0.148) (w 0.0015)))
(q/vertex 0 (+ (h 0.148) (w 0.0015)))
(q/end-shape)
; highlight on bottom border
(q/fill 220 2 60)
(q/rect 0 (h 0.148) (w 0.0685) (w 0.0005))
; lower shadow
(q/fill 0 0 0 0.75)
(q/begin-shape)
(q/vertex 0 (+ (h 0.148) (w 0.0015)))
(q/vertex (w 0.07) (+ (h 0.148) (w 0.0015)))
(doseq [x (range (w 0.07) (w -0.005) (w -0.0005))]
(let [n (q/noise (/ x (w 0.005)))
y-adjust (rescale n 0.0 1.0 (w -0.0001) (w 0.0007))]
(q/vertex x (+ (h 0.15) (w 0.0005) y-adjust))))
(q/end-shape :close)
; diagonal joint
(q/stroke 0 0 5)
(q/stroke-weight (w 0.0004))
(q/line (w 0.0685) (h 0.148)
(w 0.0696) (h 0.1505))
(q/no-stroke))
(defn sidewalk-noise
[x y]
(let [n (q/noise (/ x (w 0.01)) (/ y (w 0.01)))
y-adjust (rescale n 0.0 1.0 (h -0.0004) (h 0.0013))]
[x (+ y y-adjust)]))
(defn draw-sidewalk
[]
(q/no-stroke)
(let [left-y (h 0.984)
corner-x (w 0.105)
corner-y (h 0.99)
[_ adjusted-corner-y] (sidewalk-noise corner-x corner-y)]
(q/fill 40 7 70)
(q/begin-shape)
(doseq [t (range 0.0 1.01 0.02)]
(let [x (interpolate 0 corner-x t)
y (interpolate left-y corner-y t)]
(apply q/vertex (sidewalk-noise x y))))
(q/vertex corner-x (h))
(q/vertex 0 (h))
(q/end-shape :close)
; texture on gray part
(doseq [t (range 0.0 0.78 0.01)]
(let [x0 (interpolate 0 corner-x t)
y0 (interpolate left-y corner-y t)
[x1 y1] (sidewalk-noise x0 y0)
[x2 y2] (angular-coords x1 y1 (pi 0.77) (w 0.03))
t2 (min 1.0 (max 0.0 (q/random -0.3 1.3)))
start-x (interpolate x1 x2 t2)
start-y (interpolate y1 y2 t2)
t3 (min 1.0 (max 0.0 (q/random -0.3 1.3)))
end-x (interpolate x1 x2 t3)
end-y (interpolate y1 y2 t3)]
(q/stroke-weight (max (w 0.0001) (gauss (w 0.0003) (w 0.00015))))
(q/stroke (gauss 40 1) (gauss 7 1) (gauss 71 4))
(q/line start-x start-y end-x end-y)
(q/no-stroke)
(dotimes [_ 30]
(let [t (q/random 0.0 1.0)
x (interpolate x1 x2 t)
y (interpolate y1 y2 t)
diam (gauss (w 0.0005) (w 0.0002))]
(q/fill (gauss 40 2) (gauss 7 2) (gauss 71 5))
(q/ellipse x y diam diam)))))
; yellow top
(let [mask (q/create-graphics corner-x (h 0.03))
overlay (q/create-graphics corner-x (h 0.03))]
(q/with-graphics mask
(set-color-mode)
(q/background 0 0 0)
(q/fill 0 0 100)
(q/no-stroke)
(q/begin-shape)
(doseq [t (range 0.78 1.01 0.02)]
(let [x0 (interpolate 0 corner-x t)
y0 (interpolate left-y corner-y t)
[x1 y1] (sidewalk-noise x0 y0)]
(q/vertex x1 (- y1 (h 0.97)))))
(q/vertex (- corner-x (w 0.0050)) (h 0.03))
(q/vertex (w 0.075) (h 0.03))
(q/end-shape))
(q/with-graphics overlay
(set-color-mode)
(q/background 40 70 86)
(q/no-stroke)
(doseq [x (range 0 corner-x (w 0.0005))
y (range 0 (h 0.03) (w 0.0005))]
(let [e-width (max (w 0.0002) (gauss (w 0.0008) (w 0.0003)))
e-height (* e-width (gauss 1.0 0.05))
n (q/noise (/ x (w 0.01)) (/ y (w 0.05)))
bright-adjust (rescale n 0.0 1.0 -15.0 15.0)]
(q/fill 40 70 (gauss (+ 86 bright-adjust) 2) 0.8)
(q/ellipse x y e-width e-height))))
(.mask overlay mask)
(q/image overlay 0 (h 0.97)))
(q/stroke 30 18 30)
(q/stroke-weight (w 0.0005))
(q/begin-shape)
(q/vertex (+ corner-x (w 0.0002)) adjusted-corner-y)
(q/vertex (+ corner-x (w 0.0010)) (interpolate (h) adjusted-corner-y 0.3))
(q/vertex (+ corner-x (w 0.0011)) (h))
(q/end-shape)
; yellow highlight
(q/no-stroke)
(q/fill 40 60 98)
(q/begin-shape)
(q/vertex corner-x adjusted-corner-y)
(q/vertex (+ corner-x (w 0.0008)) (interpolate (h) adjusted-corner-y 0.3))
(q/vertex (+ corner-x (w 0.0013)) (h))
(q/vertex (- corner-x (w 0.0050)) (h))
(q/vertex (- corner-x (w 0.0035)) (interpolate (h) adjusted-corner-y 0.5))
(q/end-shape)
; brown part
(let [mask (q/create-graphics corner-x (h 0.05))
overlay (q/create-graphics corner-x (h 0.05))]
(q/with-graphics mask
(set-color-mode)
(q/background 0 0 0)
(q/no-stroke)
(q/fill 0 0 100)
(q/begin-shape)
(doseq [t (range 0 1.01 0.01)]
(let [x1 (interpolate 0 corner-x t)
y1 (interpolate left-y corner-y t)
n (q/noise (/ (- x1 (w 5.0)) (w 0.002)))
mag-max (rescale t 0 1.0 (w 0.004) (w 0.0008))
mag (rescale n 0.0 1.0 0.0 mag-max)]
(q/vertex x1 (- y1 mag (h 0.95)))))
(doseq [t (range 1.0 -0.01 -0.02)]
(let [x0 (interpolate 0 corner-x t)
y0 (interpolate left-y corner-y t)
[x1 y1] (sidewalk-noise x0 y0)]
(q/vertex x1 (+ y1 (h 0.0005) (h -0.95)))))
(q/end-shape))
(q/with-graphics overlay
(set-color-mode)
(q/background 30 38 35)
(q/no-stroke)
(dotimes [_ 3000]
(let [t (q/random 0.0 1.0)
x1 (interpolate 0 corner-x t)
y1 (interpolate left-y corner-y t)
y-offset (gauss (w 0.002) (w 0.002))
e-width (max (w 0.0001) (gauss (w 0.0005) (w 0.0005)))]
(q/fill (gauss 30 8) (max 5 (gauss 38 8)) (gauss 35 8))
(draw-dirty-dot x1 (+ y1 y-offset (h -0.95))
(* e-width 0.5)
true 0))))
(.mask overlay mask)
(q/image overlay 0 (h 0.95)))))
(defn draw-right-reflected-highlight
[near-x-right overlay-graphics mask-graphics]
(q/with-graphics mask-graphics
(q/background 0 0 0)
(q/no-stroke)
(doseq [x-offset (range 0 (w 0.05) (w 0.001))]
(let [bright (/ 104 (Math/pow (+ 1 (/ x-offset (w 0.005))) 1.2))]
(doseq [y (range 0 (h 1.02) (h 0.01))]
(let [final-bright (min 100 (max 0 (rescale y 0 (h) (* bright 1.1) (* bright -0.2))))]
(q/fill 0 0 final-bright)
(q/rect (+ near-x-right x-offset) y
(w 0.0012) (h 0.011)))))))
(q/with-graphics overlay-graphics
(q/background 0 0 100))
(.mask overlay-graphics mask-graphics)
(q/image overlay-graphics 0 0 (w) (h)))
(defn add-splatter
[]
(q/no-stroke)
(let [noise-offset-1 (q/random 0 (w 1000.0))
noise-offset-2 (q/random 0 (w 1000.0))]
(when (not= detail-level :low)
(dotimes [_ 600000]
(let [x (q/random 0 (w))
draw-odds (q/noise noise-offset-2 (/ (+ x (w 100.0)) (w 0.07)))]
(when (odds draw-odds)
(let [n1 (q/noise (/ (+ x noise-offset-1) (w 0.12)))
y-variance (rescale n1 0.0 1.0 (h 0.01) (h 0.13))
y-variance (weighted-choice
(* y-variance 15.0) 0.1
(* y-variance 7.0) 0.1
(* y-variance 3.0) 0.1
y-variance 0.7)
y (- (h) (abs-gauss 0 y-variance))
diam (max (w 0.0001) (gauss (w 0.00027) (w 0.00020)))
diam (if (odds 0.007)
(if (odds 0.5)
(* diam 2)
(* diam 3.4))
diam)
alpha (if (odds 0.02)
(min 1.0 (gauss 0.8 0.1))
(max 0.03 (min 1.0 (gauss 0.05 0.10))))
hue (if (odds 0.01)
(q/random 0 250)
(gauss 35 8))
sat (max 0 (gauss 20 10))
bright (weighted-choice
(max 8 (gauss 25 12)) 0.08
(gauss 50 12) 0.05
(gauss 60 5) 0.87)
num-reps (weighted-choice
1 0.89
2 0.05
3 0.03
4 0.02
5 0.01)]
(dotimes [_ num-reps]
(q/fill (gauss hue 2) (gauss sat 3) (gauss bright 3) (gauss alpha 0.05))
(let [diam (gauss diam (* diam 0.25))]
(if (> diam (w 0.00035))
(draw-dirty-dot (gauss x diam) (gauss y diam) (/ diam 2.0) true (pi 0.7))
(q/ellipse x y diam diam)))))))))))
(defn actual-draw
[]
(q/background 0 0 48)
(let [spacing (int (w 0.005))
left-x (w -0.1)
right-x (w 1.1)
top-y (h -0.1)
bot-y (h 1.1)
row-width (int (Math/ceil (/ (- right-x left-x) spacing)))
default-theta 0
flow-points (get-flow-points default-theta spacing left-x right-x top-y bot-y)
get-theta (fn [x y]
(let [x-offset (int (/ (- x left-x) spacing))
y-offset (int (/ (- y top-y) spacing))
index (+ x-offset (* row-width y-offset))
[_ _ theta] (if (between? index 0 (dec (count flow-points)))
(nth flow-points index)
[0 0 default-theta])]
theta))
get-offset (fn [x y]
(let [theta (get-theta x y)
mag (w 0.03)]
(angular-coords 0 0 theta mag)))
target-x-step (/ (w 1.0) 25.3333)
target-y-step (/ (h 1.0) 51.0)
grout-ratio 0.04
rear-brick-width (/ target-x-step (+ 1.0 grout-ratio))
rear-vertical-grout-spacing (* rear-brick-width grout-ratio)
horizontal-grout-ratio 0.195
; rear-brick-height (* rear-brick-width 0.295)
rear-brick-height (/ target-y-step (+ 1.0 horizontal-grout-ratio))
rear-horizontal-grout-spacing (* rear-brick-height horizontal-grout-ratio)
rear-x-step (+ rear-brick-width rear-vertical-grout-spacing)
rear-y-step (+ rear-brick-height rear-horizontal-grout-spacing)
near-brick-width (* rear-brick-height 1.01)
near-brick-height (* rear-brick-width 1.01)
near-horizontal-grout-spacing (* rear-horizontal-grout-spacing 0.7)
near-vertical-grout-spacing (* rear-vertical-grout-spacing 1.01)
near-x-step (+ near-brick-width near-vertical-grout-spacing)
near-y-step (+ near-brick-height near-horizontal-grout-spacing)
near-x-width (- (* near-x-step 10.0) (* rear-vertical-grout-spacing 1.01))
near-x-left (- (w 0.5) (* near-x-width 0.5))
near-x-right (+ (w 0.5) (* near-x-width 0.5))
near-overlay-graphics (q/create-graphics (+ near-x-step (w 0.01)) (+ near-y-step (w 0.01)))
near-mask-graphics (q/create-graphics (+ near-x-step (w 0.01)) (+ near-y-step (w 0.01)))
shadow-mask-graphics (q/create-graphics (w) (h))
shadow-overlay-graphics (q/create-graphics (w) (h))
; near-brick-mask-graphics (q/create-graphics near-x-width (h))
near-brick-overlay-graphics (q/create-graphics near-x-width (h))]
(color-grout (w))
(q/with-graphics shadow-mask-graphics
(set-color-mode)
(q/background 0 0 0)
(q/no-stroke)
(q/fill 0 0 75))
(q/with-graphics shadow-overlay-graphics
(set-color-mode)
(q/background 0 0 0)
(doseq [y (range 0 (h 1.01) (h 0.01))]
(let [ground-d (Math/pow (/ (- (h) y) (h)) 2)
bright-adjust (max 0 (rescale ground-d
0 0.25
7 0))
sat-adjust (max 0 (rescale ground-d
0 0.25
100 0))]
(q/no-stroke)
(q/fill 20 sat-adjust bright-adjust)
(q/rect 0 y (w) (h 0.011)))))
(q/with-graphics near-overlay-graphics
(set-color-mode))
(q/with-graphics near-mask-graphics
(set-color-mode)
(q/no-stroke)
(q/fill 0 0 100))
; (q/with-graphics shadow-mask-graphics
; (q/fill 0 0 75)
; (q/rect (- near-x-left (w 0.0189)) 0 (w 0.0186) (h 1.01)))
(q/with-graphics shadow-mask-graphics
(doseq [[x-offset bright] [[(w -0.00025) 50]
[(w 0.00025) 75]]]
(q/fill 0 0 bright)
(q/begin-shape)
(doseq [y (range 0 (h) (h 0.0005))]
(let [n (q/noise (/ y (w 0.02)))
x-noise-offset (rescale n 0 1.0 (w -0.001) (w 0.001))]
(q/vertex (+ near-x-left (w -0.0189) x-offset x-noise-offset) y)))
(q/vertex (+ near-x-left (w 0.0186)) (h))
(q/vertex (+ near-x-left (w 0.0186)) 0)
(q/end-shape :close)))
; rear bricks
; 25 and 1/3rd bricks wide
; 51 bricks tall
(doseq [[i y] (enumerate (range (h -0.025) (h) rear-y-step))]
(println "doing row" i)
(let [x-start (if (and (even? i) (not= i 52))
(* rear-x-step -2.9)
(* rear-x-step -2.4))
brick-width (if (= i 52)
(* rear-brick-width 0.3067)
rear-brick-width)
x-step (+ brick-width rear-vertical-grout-spacing)
rear-overlay-graphics (q/create-graphics (+ x-step (w 0.01)) (+ rear-y-step (w 0.01)))
rear-mask-graphics (q/create-graphics (+ x-step (w 0.01)) (+ rear-y-step (w 0.01)))]
(q/with-graphics rear-overlay-graphics
(set-color-mode))
(q/with-graphics rear-mask-graphics
(set-color-mode)
(q/no-stroke)
(q/fill 0 0 100))
(doseq [x (reverse (range x-start (w 1.05) x-step))]
(draw-brick
x y
brick-width rear-brick-height
rear-horizontal-grout-spacing rear-vertical-grout-spacing
rear-overlay-graphics rear-mask-graphics
shadow-mask-graphics
get-offset))))
; middle/near/vertical bricks
(q/fill 0 0 49)
(q/no-stroke)
(q/rect near-x-left 0 near-x-width (h))
(q/with-graphics near-brick-overlay-graphics
(set-color-mode)
(color-grout near-x-left))
(q/image near-brick-overlay-graphics near-x-left 0)
(q/with-graphics shadow-mask-graphics
(q/fill 0 0 0)
(q/rect near-x-left 0 near-x-width (h)))
(doseq [y (range (h -0.012) (h) near-y-step)]
(let [y-shift (gauss 0 (h 0.00038))]
(doseq [x (reverse (range near-x-left (- near-x-right (w 0.01)) near-x-step))]
(draw-brick-vertical
x (+ y y-shift)
near-brick-width near-brick-height
near-horizontal-grout-spacing near-vertical-grout-spacing
near-overlay-graphics near-mask-graphics shadow-mask-graphics))))
(add-splatter)
(q/with-graphics shadow-mask-graphics
(q/fill 0 0 75)
(q/rect (- near-x-left (w 0.0178)) 0 (w 0.017) (h)))
(draw-right-metal-piece-shadow near-x-right shadow-mask-graphics)
(.mask shadow-overlay-graphics shadow-mask-graphics)
(q/image shadow-overlay-graphics 0 0 (w) (h))
(draw-right-reflected-highlight near-x-right shadow-overlay-graphics shadow-mask-graphics)
(draw-right-metal-piece near-x-right)
(draw-left-metal-piece near-x-left)
(draw-sidewalk)
(draw-vent)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment