(local pxl8 (require :pxl8)) (local procgen (require :pxl8.procgen)) (local textures {}) (fn build-graph [seed builder] (let [g (pxl8.create_graph 128) x (g:add_node procgen.OP_INPUT_X 0 0 0 0 0) y (g:add_node procgen.OP_INPUT_Y 0 0 0 0 0) ctx {:graph g :x x :y y}] (g:set_seed seed) (let [output (builder ctx)] (g:set_output output) g))) (fn const [ctx val] (ctx.graph:add_node procgen.OP_CONST 0 0 0 0 val)) (fn add [ctx a b] (ctx.graph:add_node procgen.OP_ADD a b 0 0 0)) (fn sub [ctx a b] (ctx.graph:add_node procgen.OP_SUB a b 0 0 0)) (fn mul [ctx a b] (ctx.graph:add_node procgen.OP_MUL a b 0 0 0)) (fn div [ctx a b] (ctx.graph:add_node procgen.OP_DIV a b 0 0 0)) (fn min-op [ctx a b] (ctx.graph:add_node procgen.OP_MIN a b 0 0 0)) (fn max-op [ctx a b] (ctx.graph:add_node procgen.OP_MAX a b 0 0 0)) (fn abs [ctx a] (ctx.graph:add_node procgen.OP_ABS a 0 0 0 0)) (fn floor [ctx a] (ctx.graph:add_node procgen.OP_FLOOR a 0 0 0 0)) (fn fract [ctx a] (ctx.graph:add_node procgen.OP_FRACT a 0 0 0 0)) (fn lerp [ctx a b t] (ctx.graph:add_node procgen.OP_LERP a b t 0 0)) (fn clamp [ctx val lo hi] (ctx.graph:add_node procgen.OP_CLAMP val lo hi 0 0)) (fn select [ctx cond a b] (ctx.graph:add_node procgen.OP_SELECT a b cond 0 0)) (fn smoothstep [ctx edge0 edge1 x] (ctx.graph:add_node procgen.OP_SMOOTHSTEP edge0 edge1 x 0 0)) (fn noise-value [ctx scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_NOISE_VALUE ctx.x ctx.y s 0 0))) (fn noise-value-at [ctx x y scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_NOISE_VALUE x y s 0 0))) (fn noise-perlin [ctx scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_NOISE_PERLIN ctx.x ctx.y s 0 0))) (fn noise-fbm [ctx octaves scale persistence] (let [s (const ctx scale) p (const ctx persistence)] (ctx.graph:add_node procgen.OP_NOISE_FBM ctx.x ctx.y s p octaves))) (fn noise-fbm-at [ctx x y octaves scale persistence] (let [s (const ctx scale) p (const ctx persistence)] (ctx.graph:add_node procgen.OP_NOISE_FBM x y s p octaves))) (fn noise-ridged [ctx octaves scale persistence] (let [s (const ctx scale) p (const ctx persistence)] (ctx.graph:add_node procgen.OP_NOISE_RIDGED ctx.x ctx.y s p octaves))) (fn noise-turbulence [ctx octaves scale persistence] (let [s (const ctx scale) p (const ctx persistence)] (ctx.graph:add_node procgen.OP_NOISE_TURBULENCE ctx.x ctx.y s p octaves))) (fn voronoi-cell [ctx scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_VORONOI_CELL ctx.x ctx.y s 0 0))) (fn voronoi-edge [ctx scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_VORONOI_EDGE ctx.x ctx.y s 0 0))) (fn voronoi-id [ctx scale] (let [s (const ctx scale)] (ctx.graph:add_node procgen.OP_VORONOI_ID ctx.x ctx.y s 0 0))) (fn gradient-linear [ctx angle] (let [a (const ctx angle)] (ctx.graph:add_node procgen.OP_GRADIENT_LINEAR ctx.x ctx.y a 0 0))) (fn gradient-radial [ctx cx cy] (let [center-x (const ctx cx) center-y (const ctx cy)] (ctx.graph:add_node procgen.OP_GRADIENT_RADIAL ctx.x ctx.y center-x center-y 0))) (fn quantize [ctx val base range] (let [r (const ctx range)] (ctx.graph:add_node procgen.OP_QUANTIZE val r 0 0 base))) (fn textures.mossy-cobblestone [seed base-color moss-color] (let [g (build-graph seed (fn [ctx] (let [cell (voronoi-cell ctx 6) edge (voronoi-edge ctx 6) mortar-threshold (const ctx 0.05) is-mortar (sub ctx mortar-threshold edge) mortar-color (const ctx (- base-color 2)) stone-detail (noise-value ctx 48) stone-base (mul ctx cell (const ctx 0.6)) stone-combined (add ctx stone-base (mul ctx stone-detail (const ctx 0.4))) stone-quant (quantize ctx stone-combined base-color 8) moss-pattern (noise-fbm ctx 4 10 0.5) moss-detail (noise-value ctx 64) moss-var (add ctx (mul ctx moss-pattern (const ctx 0.7)) (mul ctx moss-detail (const ctx 0.3))) moss-threshold (const ctx 0.55) has-moss (sub ctx moss-pattern moss-threshold) moss-quant (quantize ctx moss-var moss-color 6) stone-or-moss (select ctx has-moss moss-quant stone-quant)] (select ctx is-mortar mortar-color stone-or-moss))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.ashlar-wall [seed base-color moss-color] (let [g (build-graph seed (fn [ctx] (let [cell (voronoi-cell ctx 5) edge (voronoi-edge ctx 5) cell-id (voronoi-id ctx 5) mortar-threshold (const ctx 0.12) is-mortar (sub ctx mortar-threshold edge) stone-detail (noise-fbm ctx 3 32 0.5) stone-tint (mul ctx cell-id (const ctx 0.4)) stone-shade (mul ctx cell (const ctx 0.3)) stone-combined (add ctx stone-detail (add ctx stone-tint stone-shade)) stone-quant (quantize ctx stone-combined base-color 10) crack-moss (noise-fbm ctx 3 16 0.5) moss-in-crack (mul ctx crack-moss (sub ctx (const ctx 0.2) edge)) moss-threshold (const ctx 0.06) has-moss (sub ctx moss-in-crack moss-threshold) moss-quant (quantize ctx crack-moss moss-color 4) mortar-color (const ctx (+ base-color 1)) stone-or-moss (select ctx has-moss moss-quant stone-quant)] (select ctx is-mortar mortar-color stone-or-moss))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.gradient-sky [seed zenith-color horizon-color] (let [g (build-graph seed (fn [ctx] (let [grad (gradient-linear ctx (* math.pi 0.5)) zenith (const ctx zenith-color) horizon (const ctx horizon-color) range (const ctx (- horizon-color zenith-color))] (quantize ctx grad zenith-color (- horizon-color zenith-color)))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.wood-planks [seed base-color] (let [g (build-graph seed (fn [ctx] (let [tex-size 64 plank-count 2 pixel-x (floor ctx (mul ctx ctx.x (const ctx tex-size))) plank-x (div ctx pixel-x (const ctx (/ tex-size plank-count))) plank-fract (fract ctx plank-x) edge-dist (min-op ctx plank-fract (sub ctx (const ctx 1.0) plank-fract)) gap-threshold (const ctx 0.04) is-gap (sub ctx gap-threshold edge-dist) plank-tint (mul ctx (noise-value ctx 6) (const ctx 0.25)) grain-x (mul ctx ctx.x (const ctx 12)) grain-y (mul ctx ctx.y (const ctx 2)) grain-base (noise-fbm-at ctx grain-x grain-y 3 4 0.6) grain-fine-x (mul ctx ctx.x (const ctx 48)) grain-fine-y (mul ctx ctx.y (const ctx 6)) grain-fine (noise-value-at ctx grain-fine-x grain-fine-y 1) grain (add ctx (mul ctx grain-base (const ctx 0.6)) (mul ctx grain-fine (const ctx 0.4))) wood-val (add ctx grain plank-tint) wood-quant (quantize ctx wood-val base-color 6) gap-shade (sub ctx wood-val (const ctx 0.15)) gap-quant (quantize ctx gap-shade base-color 6)] (select ctx is-gap gap-quant wood-quant))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.diagonal-planks [seed base-color] (let [g (build-graph seed (fn [ctx] (let [tex-size 64 plank-count 4 diag (add ctx ctx.x ctx.y) pixel-diag (floor ctx (mul ctx diag (const ctx tex-size))) plank-diag (div ctx pixel-diag (const ctx (/ tex-size plank-count))) plank-fract (fract ctx plank-diag) edge-dist (min-op ctx plank-fract (sub ctx (const ctx 1.0) plank-fract)) gap-threshold (const ctx 0.06) is-gap (sub ctx gap-threshold edge-dist) plank-id (floor ctx plank-diag) plank-tint (mul ctx (noise-value-at ctx plank-id (const ctx 0) 8) (const ctx 0.2)) grain-diag (mul ctx diag (const ctx 8)) grain-perp (sub ctx ctx.x ctx.y) grain-base (noise-fbm-at ctx grain-diag grain-perp 3 6 0.5) grain-fine (noise-value-at ctx (mul ctx grain-diag (const ctx 4)) grain-perp 1) grain (add ctx (mul ctx grain-base (const ctx 0.5)) (mul ctx grain-fine (const ctx 0.3))) wood-val (add ctx grain plank-tint) wood-quant (quantize ctx wood-val base-color 5) gap-shade (sub ctx wood-val (const ctx 0.2)) gap-quant (quantize ctx gap-shade base-color 5)] (select ctx is-gap gap-quant wood-quant))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.cobble-timber [seed stone-color moss-color wood-color] (let [g (build-graph seed (fn [ctx] (let [warp-x (noise-fbm ctx 2 3 0.5) warp-y (noise-value ctx 4) warped-x (add ctx ctx.x (mul ctx warp-x (const ctx 0.15))) warped-y (add ctx ctx.y (mul ctx warp-y (const ctx 0.15))) cell (ctx.graph:add_node procgen.OP_VORONOI_CELL warped-x warped-y (const ctx 5) 0 0) edge (ctx.graph:add_node procgen.OP_VORONOI_EDGE warped-x warped-y (const ctx 5) 0 0) mortar-threshold (const ctx 0.08) is-mortar (sub ctx mortar-threshold edge) mortar-color (const ctx 79) stone-detail (noise-value ctx 48) stone-base (mul ctx cell (const ctx 0.6)) stone-combined (add ctx stone-base (mul ctx stone-detail (const ctx 0.4))) stone-quant (quantize ctx stone-combined stone-color 8) moss-pattern (noise-fbm ctx 4 10 0.5) moss-detail (noise-value ctx 64) moss-var (add ctx (mul ctx moss-pattern (const ctx 0.7)) (mul ctx moss-detail (const ctx 0.3))) moss-threshold (const ctx 0.55) has-moss (sub ctx moss-pattern moss-threshold) moss-quant (quantize ctx moss-var moss-color 6) stone-or-moss (select ctx has-moss moss-quant stone-quant)] (select ctx is-mortar mortar-color stone-or-moss))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.plaster-wall [seed base-color] (let [g (build-graph seed (fn [ctx] (let [plaster-base (noise-fbm ctx 3 24 0.4) plaster-detail (noise-value ctx 64) plaster-rough (noise-turbulence ctx 2 32 0.5) combined (add ctx (mul ctx plaster-base (const ctx 0.5)) (add ctx (mul ctx plaster-detail (const ctx 0.3)) (mul ctx plaster-rough (const ctx 0.2)))) crack-noise (noise-ridged ctx 2 8 0.6) crack-threshold (const ctx 0.75) has-crack (sub ctx crack-noise crack-threshold) crack-color (const ctx (- base-color 2)) plaster-quant (quantize ctx combined base-color 4)] (select ctx has-crack crack-color plaster-quant))))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.timber-frame [seed wood-color plaster-color] (let [g (build-graph seed (fn [ctx] (let [h-beam-count 2 v-beam-count 1.5 beam-half-width 0.08 scaled-x (mul ctx ctx.x (const ctx h-beam-count)) scaled-y (mul ctx ctx.y (const ctx v-beam-count)) dist-to-h-beam (abs ctx (sub ctx (fract ctx scaled-y) (const ctx 0.5))) dist-to-v-beam (abs ctx (sub ctx (fract ctx scaled-x) (const ctx 0.5))) is-h-timber (sub ctx beam-half-width dist-to-h-beam) is-v-timber (sub ctx beam-half-width dist-to-v-beam) wood-grain (noise-fbm ctx 2 48 0.5) wood-quant (quantize ctx wood-grain wood-color 4) plaster-noise (noise-fbm ctx 3 16 0.4) plaster-quant (quantize ctx plaster-noise plaster-color 3) timber-or-plaster (select ctx is-h-timber wood-quant (select ctx is-v-timber wood-quant plaster-quant))] timber-or-plaster)))] (let [tex-id (g:eval_texture 64 64)] (g:destroy) tex-id))) (fn textures.door [] (let [(tex err) (pxl8.load_sprite "res/textures/door.ase")] (if tex tex (do (pxl8.error (.. "Failed to load res/textures/door.ase, error: " (tostring err))) nil)))) (fn textures.wood-trim [seed base-color] (let [g (build-graph seed (fn [ctx] (let [plank-tint (mul ctx (noise-value ctx 6) (const ctx 0.25)) grain-x (mul ctx ctx.x (const ctx 12)) grain-y (mul ctx ctx.y (const ctx 2)) grain-base (noise-fbm-at ctx grain-x grain-y 3 4 0.6) grain-fine-x (mul ctx ctx.x (const ctx 48)) grain-fine-y (mul ctx ctx.y (const ctx 6)) grain-fine (noise-value-at ctx grain-fine-x grain-fine-y 1) grain (add ctx (mul ctx grain-base (const ctx 0.6)) (mul ctx grain-fine (const ctx 0.4))) wood-val (add ctx grain plank-tint)] (quantize ctx wood-val base-color 6))))] (let [tex-id (g:eval_texture 64 16)] (g:destroy) tex-id))) textures