refactor separate framework from game code, add demo3d
This commit is contained in:
parent
19ae869769
commit
40f5cdcaa5
92 changed files with 2665 additions and 6547 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,132 +0,0 @@
|
|||
(local pxl8 (require :pxl8))
|
||||
|
||||
(local FIREBALL_COLOR 218)
|
||||
|
||||
(var fireball-mesh nil)
|
||||
|
||||
(fn create-fireball-mesh []
|
||||
(let [verts []
|
||||
indices []
|
||||
radius 5
|
||||
rings 4
|
||||
segments 6
|
||||
core-color (+ FIREBALL_COLOR 6)
|
||||
spike-color (- FIREBALL_COLOR 1)]
|
||||
|
||||
(table.insert verts {:x 0 :y radius :z 0 :nx 0 :ny 1 :nz 0 :color core-color :light 255})
|
||||
|
||||
(for [ring 1 (- rings 1)]
|
||||
(let [phi (* (/ ring rings) math.pi)
|
||||
sin-phi (math.sin phi)
|
||||
cos-phi (math.cos phi)
|
||||
y (* radius cos-phi)
|
||||
ring-radius (* radius sin-phi)]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [theta (* (/ seg segments) math.pi 2)
|
||||
x (* ring-radius (math.cos theta))
|
||||
z (* ring-radius (math.sin theta))
|
||||
nx (* sin-phi (math.cos theta))
|
||||
nz (* sin-phi (math.sin theta))]
|
||||
(table.insert verts {:x x :y y :z z :nx nx :ny cos-phi :nz nz :color core-color :light 255})))))
|
||||
|
||||
(let [bottom-idx (length verts)]
|
||||
(table.insert verts {:x 0 :y (- radius) :z 0 :nx 0 :ny -1 :nz 0 :color core-color :light 255})
|
||||
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)]
|
||||
(table.insert indices 0)
|
||||
(table.insert indices (+ 1 next-seg))
|
||||
(table.insert indices (+ 1 seg))))
|
||||
|
||||
(for [ring 0 (- rings 3)]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)
|
||||
curr-row (+ 1 (* ring segments))
|
||||
next-row (+ 1 (* (+ ring 1) segments))]
|
||||
(table.insert indices (+ curr-row seg))
|
||||
(table.insert indices (+ curr-row next-seg))
|
||||
(table.insert indices (+ next-row seg))
|
||||
(table.insert indices (+ curr-row next-seg))
|
||||
(table.insert indices (+ next-row next-seg))
|
||||
(table.insert indices (+ next-row seg)))))
|
||||
|
||||
(let [last-ring-start (+ 1 (* (- rings 2) segments))]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)]
|
||||
(table.insert indices bottom-idx)
|
||||
(table.insert indices (+ last-ring-start seg))
|
||||
(table.insert indices (+ last-ring-start next-seg))))))
|
||||
|
||||
(let [num-spikes 12
|
||||
spike-len 8
|
||||
base-size 1.2
|
||||
golden-ratio (/ (+ 1 (math.sqrt 5)) 2)]
|
||||
(for [i 0 (- num-spikes 1)]
|
||||
(let [y (- 1 (* (/ i (- num-spikes 1)) 2))
|
||||
r-at-y (math.sqrt (- 1 (* y y)))
|
||||
theta (* math.pi 2 i golden-ratio)
|
||||
nx (* r-at-y (math.cos theta))
|
||||
ny y
|
||||
nz (* r-at-y (math.sin theta))
|
||||
tx (if (> (math.abs ny) 0.9) 1 0)
|
||||
ty (if (> (math.abs ny) 0.9) 0 1)
|
||||
tz 0
|
||||
px (- (* ty nz) (* tz ny))
|
||||
py (- (* tz nx) (* tx nz))
|
||||
pz (- (* tx ny) (* ty nx))
|
||||
pl (math.sqrt (+ (* px px) (* py py) (* pz pz)))
|
||||
px (/ px pl) py (/ py pl) pz (/ pz pl)
|
||||
qx (- (* ny pz) (* nz py))
|
||||
qy (- (* nz px) (* nx pz))
|
||||
qz (- (* nx py) (* ny px))
|
||||
bx (* radius 0.8 nx)
|
||||
by (* radius 0.8 ny)
|
||||
bz (* radius 0.8 nz)
|
||||
sx (* (+ radius spike-len) nx)
|
||||
sy (* (+ radius spike-len) ny)
|
||||
sz (* (+ radius spike-len) nz)
|
||||
base-idx (length verts)]
|
||||
(table.insert verts {:x (+ bx (* base-size px) (* base-size qx))
|
||||
:y (+ by (* base-size py) (* base-size qy))
|
||||
:z (+ bz (* base-size pz) (* base-size qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* base-size px) (* (- base-size) qx))
|
||||
:y (+ by (* base-size py) (* (- base-size) qy))
|
||||
:z (+ bz (* base-size pz) (* (- base-size) qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* (- base-size) px) (* (- base-size) qx))
|
||||
:y (+ by (* (- base-size) py) (* (- base-size) qy))
|
||||
:z (+ bz (* (- base-size) pz) (* (- base-size) qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* (- base-size) px) (* base-size qx))
|
||||
:y (+ by (* (- base-size) py) (* base-size qy))
|
||||
:z (+ bz (* (- base-size) pz) (* base-size qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x sx :y sy :z sz :nx nx :ny ny :nz nz :color spike-color :light 255})
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 1))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 1))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 4)))))
|
||||
|
||||
(set fireball-mesh (pxl8.create_mesh verts indices))))
|
||||
|
||||
(fn init [textures]
|
||||
(when (not fireball-mesh)
|
||||
(create-fireball-mesh)))
|
||||
|
||||
(fn render-fireball [x y z]
|
||||
(when fireball-mesh
|
||||
(pxl8.draw_mesh fireball-mesh {:x x :y y :z z
|
||||
:emissive true})))
|
||||
|
||||
{:FIREBALL_COLOR FIREBALL_COLOR
|
||||
:init init
|
||||
:render-fireball render-fireball}
|
||||
|
|
@ -1,282 +0,0 @@
|
|||
(local pxl8 (require :pxl8))
|
||||
(local bit (require :bit))
|
||||
(local effects (require :pxl8.effects))
|
||||
(local net (require :pxl8.net))
|
||||
|
||||
(local entities (require :mod.entities))
|
||||
(local menu (require :mod.menu))
|
||||
(local sky (require :mod.sky))
|
||||
(local textures (require :mod.textures))
|
||||
|
||||
(local bob-amount 3.0)
|
||||
(local bob-speed 6.0)
|
||||
(local cam-smoothing 0.25)
|
||||
(local land-recovery-speed 20)
|
||||
(local land-squash-amount -4)
|
||||
(local player-eye-height 64)
|
||||
(local day-length 1800)
|
||||
|
||||
(local SIM_FLAG_GROUNDED 4)
|
||||
|
||||
(local sim-cfg (pxl8.sim_config {:move_speed 150
|
||||
:gravity 600
|
||||
:jump_velocity 180
|
||||
:player_radius 12
|
||||
:player_height 72
|
||||
:max_pitch 1.5
|
||||
:friction 6.0
|
||||
:ground_accel 10.0
|
||||
:air_accel 1.0
|
||||
:stop_speed 100.0}))
|
||||
|
||||
(var auto-run-cancel-key nil)
|
||||
(var auto-run? false)
|
||||
(var bob-time 0)
|
||||
(var cam-pitch 0)
|
||||
(var day-time 0)
|
||||
(var cam-x 416)
|
||||
(var cam-y 0)
|
||||
(var cam-yaw 0)
|
||||
(var cam-z 416)
|
||||
(var camera nil)
|
||||
(var land-squash 0)
|
||||
(var last-dt 0.016)
|
||||
(var light-time 0)
|
||||
(var glows nil)
|
||||
(var lights nil)
|
||||
(var materials-set? false)
|
||||
(var network nil)
|
||||
(var real-time 0)
|
||||
(var smooth-cam-x 416)
|
||||
(var smooth-cam-z 416)
|
||||
(var was-grounded true)
|
||||
(var world nil)
|
||||
|
||||
(local MOSS_COLOR 200)
|
||||
(local GRASS_COLOR 200)
|
||||
(local STONE_WALL_START 2)
|
||||
(local WOOD_COLOR 88)
|
||||
|
||||
(local ASHLAR_COLOR 64)
|
||||
(local ASHLAR_MOSS 68)
|
||||
(local STONE_FLOOR_COLOR 72)
|
||||
(local STONE_TRIM_COLOR 72)
|
||||
|
||||
(fn preload []
|
||||
(when (not network)
|
||||
(set network (net.get))
|
||||
(when network
|
||||
(network:spawn cam-x cam-y cam-z cam-yaw cam-pitch)))
|
||||
(when (not world)
|
||||
(set world (pxl8.get_world))
|
||||
(when world
|
||||
(world:set_sim_config sim-cfg))))
|
||||
|
||||
(fn is-connected []
|
||||
(and network (network:connected)))
|
||||
|
||||
(fn is-ready []
|
||||
(if (not world)
|
||||
false
|
||||
(let [chunk (world:active_chunk)]
|
||||
(and chunk (chunk:ready)))))
|
||||
|
||||
(fn init []
|
||||
(pxl8.set_relative_mouse_mode true)
|
||||
(pxl8.load_palette "res/palettes/palette.ase")
|
||||
(for [i 0 7]
|
||||
(let [t (/ i 7)
|
||||
r 0xFF
|
||||
g (math.floor (+ 0x60 (* t (- 0xE0 0x60))))
|
||||
b (math.floor (+ 0x10 (* t (- 0x80 0x10))))]
|
||||
(pxl8.set_palette_rgb (+ entities.FIREBALL_COLOR i) r g b)))
|
||||
(pxl8.set_palette_rgb (- entities.FIREBALL_COLOR 1) 0xFF 0x20 0x10)
|
||||
(sky.reset-gradient)
|
||||
(sky.update-gradient 1 2 6 6 10 18)
|
||||
(pxl8.update_palette_deps)
|
||||
|
||||
(when (not camera)
|
||||
(set camera (pxl8.create_camera_3d)))
|
||||
(when (not glows)
|
||||
(set glows (pxl8.create_glows)))
|
||||
(when (not lights)
|
||||
(set lights (pxl8.create_lights)))
|
||||
|
||||
(entities.init textures)
|
||||
(sky.generate-stars)
|
||||
(preload)
|
||||
|
||||
(when world
|
||||
(world:init_local_player cam-x cam-y cam-z)
|
||||
(set smooth-cam-x cam-x)
|
||||
(set smooth-cam-z cam-z)))
|
||||
|
||||
(fn setup-materials []
|
||||
(when (not world) (lua "return"))
|
||||
(when (not network) (lua "return"))
|
||||
(when materials-set? (lua "return"))
|
||||
(when (not (network:has_chunk)) (lua "return"))
|
||||
(let [chunk (world:active_chunk)]
|
||||
(when (not chunk) (lua "return"))
|
||||
(when (not (chunk:ready)) (lua "return"))
|
||||
(let [dungeon-floor-tex (textures.wood-planks 44444 WOOD_COLOR)
|
||||
dungeon-wall-tex (textures.cobble-timber 55555 STONE_WALL_START MOSS_COLOR WOOD_COLOR)
|
||||
dungeon-trim-tex (textures.wood-trim 77777 WOOD_COLOR)
|
||||
court-floor-tex (textures.rough-stone 44442 STONE_FLOOR_COLOR)
|
||||
court-wall-tex (textures.ashlar-wall 55552 ASHLAR_COLOR ASHLAR_MOSS)
|
||||
court-trim-tex (textures.rough-stone 77772 STONE_TRIM_COLOR)
|
||||
grass-tex (textures.grass-top 44447 GRASS_COLOR)
|
||||
dungeon-floor-mat (pxl8.create_material {:texture dungeon-floor-tex :lighting true :double_sided true})
|
||||
dungeon-wall-mat (pxl8.create_material {:texture dungeon-wall-tex :lighting true :double_sided true})
|
||||
dungeon-trim-mat (pxl8.create_material {:texture dungeon-trim-tex :lighting true :double_sided true})
|
||||
court-floor-mat (pxl8.create_material {:texture court-floor-tex :lighting true :double_sided true})
|
||||
court-wall-mat (pxl8.create_material {:texture court-wall-tex :lighting true :double_sided true})
|
||||
court-trim-mat (pxl8.create_material {:texture court-trim-tex :lighting true :double_sided true})
|
||||
grass-mat (pxl8.create_material {:texture grass-tex :lighting true :double_sided true})]
|
||||
(world:set_bsp_material 0 dungeon-floor-mat)
|
||||
(world:set_bsp_material 1 dungeon-wall-mat)
|
||||
(world:set_bsp_material 3 dungeon-trim-mat)
|
||||
(world:set_bsp_material 4 court-floor-mat)
|
||||
(world:set_bsp_material 5 court-wall-mat)
|
||||
(world:set_bsp_material 6 court-trim-mat)
|
||||
(world:set_bsp_material 7 grass-mat)
|
||||
(set materials-set? true))))
|
||||
|
||||
(fn sample-input []
|
||||
(when (pxl8.key_pressed "`")
|
||||
(set auto-run? (not auto-run?))
|
||||
(when (and auto-run? (pxl8.key_down "w"))
|
||||
(set auto-run-cancel-key "w")))
|
||||
(when (and auto-run? (not auto-run-cancel-key) (or (pxl8.key_down "w") (pxl8.key_down "s")))
|
||||
(set auto-run? false)
|
||||
(when (pxl8.key_down "s")
|
||||
(set auto-run-cancel-key "s")))
|
||||
(when (and auto-run-cancel-key (not (pxl8.key_down auto-run-cancel-key)))
|
||||
(set auto-run-cancel-key nil))
|
||||
|
||||
(pxl8.make_input_msg
|
||||
{:move_x (+ (if (pxl8.key_down "d") 1 0) (if (pxl8.key_down "a") -1 0))
|
||||
:move_y (+ (if (or (pxl8.key_down "w") auto-run?) 1 0)
|
||||
(if (and (pxl8.key_down "s") (not= auto-run-cancel-key "s")) -1 0))
|
||||
:look_dx (pxl8.mouse_dx)
|
||||
:look_dy (pxl8.mouse_dy)
|
||||
:buttons (if (pxl8.key_down "space") 1 0)}))
|
||||
|
||||
(fn update [dt]
|
||||
(set last-dt dt)
|
||||
(setup-materials)
|
||||
|
||||
(when world
|
||||
(let [input-msg (sample-input)
|
||||
player (world:local_player)]
|
||||
|
||||
(world:push_input input-msg)
|
||||
|
||||
(when player
|
||||
(set cam-x player.pos.x)
|
||||
(set cam-y player.pos.y)
|
||||
(set cam-z player.pos.z)
|
||||
(set cam-yaw player.yaw)
|
||||
(set cam-pitch player.pitch))
|
||||
|
||||
(let [now-grounded (if player (not= (bit.band player.flags SIM_FLAG_GROUNDED) 0) true)]
|
||||
(when (and (not was-grounded) now-grounded)
|
||||
(set land-squash land-squash-amount))
|
||||
(set was-grounded now-grounded))
|
||||
|
||||
(set smooth-cam-x (+ (* smooth-cam-x (- 1 cam-smoothing)) (* cam-x cam-smoothing)))
|
||||
(set smooth-cam-z (+ (* smooth-cam-z (- 1 cam-smoothing)) (* cam-z cam-smoothing)))
|
||||
|
||||
(when (< land-squash 0)
|
||||
(set land-squash (math.min 0 (+ land-squash (* land-recovery-speed dt)))))
|
||||
|
||||
(let [moving (or (not= input-msg.move_x 0) (not= input-msg.move_y 0))]
|
||||
(if (and moving was-grounded)
|
||||
(set bob-time (+ bob-time (* dt bob-speed)))
|
||||
(let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)]
|
||||
(set bob-time (+ (* bob-time 0.8) (* target-phase 0.2))))))
|
||||
|
||||
(set day-time (% (+ day-time (/ dt day-length)) 1))
|
||||
(set light-time (+ light-time (* dt 0.5)))
|
||||
(set real-time (+ real-time dt)))))
|
||||
|
||||
(fn frame []
|
||||
(pxl8.clear 1)
|
||||
|
||||
(when (or (not camera) (not world))
|
||||
(lua "return"))
|
||||
|
||||
(let [chunk (when world (world:active_chunk))
|
||||
ready (and chunk (chunk:ready))]
|
||||
|
||||
(when ready
|
||||
(let [bob-offset (* (math.sin bob-time) bob-amount)
|
||||
eye-y (+ cam-y player-eye-height bob-offset land-squash)
|
||||
forward-x (- (math.sin cam-yaw))
|
||||
forward-z (- (math.cos cam-yaw))
|
||||
target-x (+ smooth-cam-x forward-x)
|
||||
target-y (+ eye-y (math.sin cam-pitch))
|
||||
target-z (+ smooth-cam-z forward-z)
|
||||
aspect (/ (pxl8.get_width) (pxl8.get_height))]
|
||||
|
||||
(camera:lookat [smooth-cam-x eye-y smooth-cam-z]
|
||||
[target-x target-y target-z]
|
||||
[0 1 0])
|
||||
(camera:set_perspective 1.047 aspect 1.0 4096.0)
|
||||
|
||||
(let [light-x (+ 384 (* 50 (math.cos light-time)))
|
||||
light-z (+ 324 (* 50 (math.sin light-time)))
|
||||
light-y 80
|
||||
phase (+ (* light-x 0.01) 1.7)
|
||||
f1 (* 0.08 (math.sin (+ (* real-time 2.5) phase)))
|
||||
f2 (* 0.05 (math.sin (+ (* real-time 4.1) (* phase 0.7))))
|
||||
f3 (* 0.03 (math.sin (+ (* real-time 7.3) (* phase 1.2))))
|
||||
flicker (+ 0.92 f1 f2 f3)
|
||||
light-intensity (math.floor (math.max 0 (math.min 255 (* 255 flicker))))
|
||||
r1 (* 0.06 (math.sin (+ (* real-time 1.8) (* phase 0.5))))
|
||||
r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase)))
|
||||
light-radius (* 150 (+ 0.95 r1 r2))]
|
||||
(lights:clear)
|
||||
(lights:add light-x light-y light-z 2 light-intensity light-radius)
|
||||
|
||||
(pxl8.push_target)
|
||||
(pxl8.begin_frame_3d camera lights {
|
||||
:ambient 2
|
||||
:dither true
|
||||
:fog_density 0.002
|
||||
:celestial_dir [0.5 -0.8 0.3]
|
||||
:celestial_intensity 0.3})
|
||||
|
||||
(when (not (menu.is-wireframe))
|
||||
(sky.update-gradient 1 2 6 6 10 18))
|
||||
(sky.render smooth-cam-x eye-y smooth-cam-z (menu.is-wireframe))
|
||||
(pxl8.clear_depth)
|
||||
|
||||
(pxl8.set_wireframe (menu.is-wireframe))
|
||||
(world:render [smooth-cam-x eye-y smooth-cam-z])
|
||||
|
||||
(when chunk
|
||||
(entities.render-fireball light-x light-y light-z))
|
||||
|
||||
(pxl8.end_frame_3d)
|
||||
|
||||
(when (not (menu.is-wireframe))
|
||||
(sky.render-stars smooth-cam-x eye-y smooth-cam-z day-time 0 last-dt))
|
||||
|
||||
(pxl8.pop_target))
|
||||
|
||||
(pxl8.push_target)
|
||||
(let [cx (/ (pxl8.get_width) 2)
|
||||
cy (/ (pxl8.get_height) 2)
|
||||
crosshair-size 4
|
||||
crosshair-color 240]
|
||||
(pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy crosshair-color)
|
||||
(pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) crosshair-color))
|
||||
(pxl8.pop_target)))))
|
||||
|
||||
{:preload preload
|
||||
:is-connected is-connected
|
||||
:is-ready is-ready
|
||||
:init init
|
||||
:update update
|
||||
:frame frame}
|
||||
505
demo/mod/sky.fnl
505
demo/mod/sky.fnl
|
|
@ -1,505 +0,0 @@
|
|||
(local pxl8 (require :pxl8))
|
||||
|
||||
(local SKY_GRADIENT_START 144)
|
||||
(local SKY_GRADIENT_COUNT 16)
|
||||
(local sky-radius 900)
|
||||
(local sky-segments 16)
|
||||
(local sky-rings 16)
|
||||
|
||||
(local NUM_RANDOM_STARS 300)
|
||||
(local NUM_TINY_STARS 7000)
|
||||
(local NUM_BEACON_STARS 8)
|
||||
(local STAR_SEED 0xDEADBEEF)
|
||||
(local STAR_CYCLE_DAYS 90)
|
||||
(local TAU (* math.pi 2))
|
||||
|
||||
(local GLOW_TORCH pxl8.LIGHT_ORANGE)
|
||||
(local GLOW_MAGIC pxl8.LIGHT_PURPLE)
|
||||
(local GLOW_SILVER pxl8.LIGHT_WHITE)
|
||||
(local GLOW_CRIMSON pxl8.LIGHT_RED)
|
||||
(local GLOW_DEEP_BLUE pxl8.LIGHT_BLUE)
|
||||
|
||||
(local CONSTELLATIONS
|
||||
[{:stars [[-0.09 0.075 240] [-0.12 0.105 200] [-0.075 0.112 190]
|
||||
[-0.06 0.045 255] [-0.022 0.022 220] [0.03 0.0 200]
|
||||
[0.075 -0.018 190] [0.12 -0.009 180] [0.158 0.022 170]
|
||||
[0.18 0.06 160] [0.15 0.075 150]]}
|
||||
{:stars [[0.0 0.0 240] [0.04 0.0 220] [0.08 0.01 200]
|
||||
[0.08 0.05 190] [0.04 0.06 180] [0.0 0.05 200]
|
||||
[-0.02 0.08 170]]}
|
||||
{:stars [[-0.03 0.04 230] [0.03 0.04 230] [0.05 0.0 200]
|
||||
[0.03 -0.04 190] [-0.03 -0.04 190] [-0.05 0.0 200]
|
||||
[0.0 -0.06 170]]}
|
||||
{:stars [[-0.06 0.04 255] [-0.03 0.02 220] [0.0 0.0 240]
|
||||
[0.04 -0.025 200] [0.08 -0.05 180] [0.12 -0.075 160]
|
||||
[-0.02 -0.03 190] [-0.02 0.04 190]]}
|
||||
{:stars [[0.0 0.0 250] [-0.015 0.022 200] [-0.03 0.04 180]
|
||||
[0.015 0.015 190] [0.035 0.03 170] [0.0 -0.022 200]
|
||||
[-0.022 -0.038 180] [0.022 -0.038 180]
|
||||
[0.045 0.0 220] [0.07 0.0 200] [0.09 0.008 180]]}
|
||||
{:stars [[-0.06 0.0 200] [-0.03 0.015 210] [0.0 0.0 230]
|
||||
[0.03 -0.015 210] [0.06 0.0 200] [0.09 0.015 190]
|
||||
[0.12 0.0 180]]}
|
||||
{:stars [[0.0 0.0 250] [0.008 0.03 220] [-0.02 0.05 200]
|
||||
[0.015 0.055 190] [-0.035 0.07 170] [0.03 0.065 180]
|
||||
[0.0 -0.02 200] [-0.015 -0.045 180]]}
|
||||
{:stars [[0.0 0.0 255] [-0.025 0.012 200] [-0.055 0.018 180]
|
||||
[-0.08 0.012 160] [0.02 0.01 190] [0.045 0.018 180]
|
||||
[0.07 0.03 160] [0.0 -0.025 190]]}
|
||||
{:stars [[0.0 0.0 240] [0.03 0.025 220] [0.05 0.05 200]
|
||||
[-0.02 0.03 200] [-0.05 0.045 180] [0.01 -0.03 210]
|
||||
[0.04 -0.05 190] [-0.03 -0.06 170]]}
|
||||
{:stars [[0.0 0.0 230] [0.045 0.01 220] [0.025 0.04 210]
|
||||
[-0.015 0.035 200] [-0.04 0.005 210] [-0.025 -0.03 200]
|
||||
[0.02 -0.04 190]]}
|
||||
{:stars [[0.0 0.0 250] [0.05 0.015 200] [0.035 0.05 190]
|
||||
[-0.02 0.055 180] [-0.055 0.025 200] [-0.045 -0.025 190]
|
||||
[-0.01 -0.05 180] [0.04 -0.04 190]]}
|
||||
{:stars [[0.0 0.0 255] [0.025 0.015 180] [-0.015 0.025 170]
|
||||
[0.02 -0.025 175] [-0.03 -0.01 165]]}])
|
||||
|
||||
(var beacon-stars [])
|
||||
(var celestial-directions nil)
|
||||
(var celestial-projected nil)
|
||||
(var constellation-stars [])
|
||||
(var last-gradient-key nil)
|
||||
(var random-stars [])
|
||||
(var sky-mesh nil)
|
||||
(var star-count 0)
|
||||
(var star-directions nil)
|
||||
(var star-glows nil)
|
||||
(var star-projected nil)
|
||||
(var tiny-stars [])
|
||||
(var twinkle-time 0)
|
||||
|
||||
(fn generate-sky-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b]
|
||||
(for [i 0 (- SKY_GRADIENT_COUNT 1)]
|
||||
(let [t (/ i (- SKY_GRADIENT_COUNT 1))
|
||||
r (math.floor (+ zenith-r (* t (- horizon-r zenith-r))))
|
||||
g (math.floor (+ zenith-g (* t (- horizon-g zenith-g))))
|
||||
b (math.floor (+ zenith-b (* t (- horizon-b zenith-b))))]
|
||||
(pxl8.set_palette_rgb (+ SKY_GRADIENT_START i) r g b))))
|
||||
|
||||
(fn create-sky-dome []
|
||||
(let [verts []
|
||||
indices []]
|
||||
|
||||
(for [i 0 (- sky-rings 1)]
|
||||
(let [theta0 (* (/ i sky-rings) math.pi 0.5)
|
||||
theta1 (* (/ (+ i 1) sky-rings) math.pi 0.5)
|
||||
sin-t0 (math.sin theta0)
|
||||
cos-t0 (math.cos theta0)
|
||||
sin-t1 (math.sin theta1)
|
||||
cos-t1 (math.cos theta1)
|
||||
y0 (* sky-radius cos-t0)
|
||||
y1 (* sky-radius cos-t1)
|
||||
r0 (* sky-radius sin-t0)
|
||||
r1 (* sky-radius sin-t1)
|
||||
t0 (/ i sky-rings)
|
||||
t1 (/ (+ i 1) sky-rings)
|
||||
c0 (math.floor (+ SKY_GRADIENT_START (* t0 (- SKY_GRADIENT_COUNT 1)) 0.5))
|
||||
c1 (math.floor (+ SKY_GRADIENT_START (* t1 (- SKY_GRADIENT_COUNT 1)) 0.5))]
|
||||
|
||||
(for [j 0 (- sky-segments 1)]
|
||||
(let [phi0 (* (/ j sky-segments) math.pi 2)
|
||||
phi1 (* (/ (+ j 1) sky-segments) math.pi 2)
|
||||
cos-p0 (math.cos phi0)
|
||||
sin-p0 (math.sin phi0)
|
||||
cos-p1 (math.cos phi1)
|
||||
sin-p1 (math.sin phi1)
|
||||
x00 (* r0 cos-p0) z00 (* r0 sin-p0)
|
||||
x01 (* r0 cos-p1) z01 (* r0 sin-p1)
|
||||
x10 (* r1 cos-p0) z10 (* r1 sin-p0)
|
||||
x11 (* r1 cos-p1) z11 (* r1 sin-p1)
|
||||
nx00 (- (* sin-t0 cos-p0)) ny00 (- cos-t0) nz00 (- (* sin-t0 sin-p0))
|
||||
nx01 (- (* sin-t0 cos-p1)) ny01 (- cos-t0) nz01 (- (* sin-t0 sin-p1))
|
||||
nx10 (- (* sin-t1 cos-p0)) ny10 (- cos-t1) nz10 (- (* sin-t1 sin-p0))
|
||||
nx11 (- (* sin-t1 cos-p1)) ny11 (- cos-t1) nz11 (- (* sin-t1 sin-p1))
|
||||
base-idx (# verts)]
|
||||
|
||||
(if (= i 0)
|
||||
(do
|
||||
(table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255})
|
||||
(table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255})
|
||||
(table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255})
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 1)))
|
||||
(do
|
||||
(table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255})
|
||||
(table.insert verts {:x x01 :y y0 :z z01 :nx nx01 :ny ny01 :nz nz01 :color c0 :light 255})
|
||||
(table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255})
|
||||
(table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255})
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 1))))))))
|
||||
|
||||
(set sky-mesh (pxl8.create_mesh verts indices))))
|
||||
|
||||
(fn reset-gradient []
|
||||
(set last-gradient-key nil))
|
||||
|
||||
(fn update-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b]
|
||||
(let [key (.. zenith-r "," zenith-g "," zenith-b "," horizon-r "," horizon-g "," horizon-b)]
|
||||
(when (not= key last-gradient-key)
|
||||
(generate-sky-gradient zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b)
|
||||
(set last-gradient-key key))))
|
||||
|
||||
(fn galactic-band-factor [dx dy dz]
|
||||
(let [band-len (math.sqrt (+ (* 0.6 0.6) (* 0.3 0.3) (* 0.742 0.742)))
|
||||
bx (/ 0.6 band-len)
|
||||
by (/ 0.3 band-len)
|
||||
bz (/ 0.742 band-len)
|
||||
dist (math.abs (+ (* dx bx) (* dy by) (* dz bz)))
|
||||
in-band (- 1 (math.min (* dist 3) 1))]
|
||||
(* in-band in-band)))
|
||||
|
||||
(fn compute-right [cx cy cz]
|
||||
(if (> (math.abs cy) 0.99)
|
||||
(values 1 0 0)
|
||||
(let [rx (- cz)
|
||||
rz cx
|
||||
rlen (math.sqrt (+ (* rx rx) (* rz rz)))]
|
||||
(values (/ rx rlen) 0 (/ rz rlen)))))
|
||||
|
||||
(fn generate-constellation-centers []
|
||||
(let [centers []
|
||||
seed (+ STAR_SEED 0xC0057E11)
|
||||
num (# CONSTELLATIONS)]
|
||||
(for [i 0 (- num 1)]
|
||||
(let [h1 (pxl8.hash32 (+ seed (* i 3)))
|
||||
h2 (pxl8.hash32 (+ seed (* i 3) 1))
|
||||
h1f (/ h1 0xFFFFFFFF)
|
||||
h2f (/ h2 0xFFFFFFFF)
|
||||
base-theta (* (/ i num) TAU)
|
||||
theta-jitter (* (- h1f 0.5) 0.3)
|
||||
theta-offset (if (= i 0) -0.3 (= i 1) 0.4 (= i 4) 0.5 0)
|
||||
theta (+ base-theta theta-jitter theta-offset)
|
||||
phi (if (or (= i 0) (= i 6)) (+ 0.25 (* h2f 0.3))
|
||||
(= i 9) (+ 0.5 (* h2f 0.3))
|
||||
(or (= i 1) (= i 4) (= i 7) (= i 10)) (+ 0.65 (* h2f 0.4))
|
||||
(= i 3) (+ 1.1 (* h2f 0.2))
|
||||
(+ 0.85 (* h2f 0.4)))
|
||||
sin-phi (math.sin phi)
|
||||
x (* sin-phi (math.cos theta))
|
||||
y (math.cos phi)
|
||||
z (* sin-phi (math.sin theta))
|
||||
len (math.sqrt (+ (* x x) (* y y) (* z z)))]
|
||||
(table.insert centers {:x (/ x len) :y (/ y len) :z (/ z len)})))
|
||||
centers))
|
||||
|
||||
(fn generate-constellation-stars-data []
|
||||
(let [centers (generate-constellation-centers)
|
||||
stars []]
|
||||
(for [i 0 (- (# CONSTELLATIONS) 1)]
|
||||
(let [constellation (. CONSTELLATIONS (+ i 1))
|
||||
center (. centers (+ i 1))
|
||||
(rx ry rz) (compute-right center.x center.y center.z)
|
||||
ux (- (* center.y rz) (* center.z ry))
|
||||
uy (- (* center.z rx) (* center.x rz))
|
||||
uz (- (* center.x ry) (* center.y rx))
|
||||
ulen (math.sqrt (+ (* ux ux) (* uy uy) (* uz uz)))
|
||||
ux (/ ux ulen) uy (/ uy ulen) uz (/ uz ulen)]
|
||||
(each [j star-data (ipairs constellation.stars)]
|
||||
(let [ox (. star-data 1)
|
||||
oy (. star-data 2)
|
||||
brightness (. star-data 3)
|
||||
dx (+ center.x (* rx ox) (* ux oy))
|
||||
dy (+ center.y (* ry ox) (* uy oy))
|
||||
dz (+ center.z (* rz ox) (* uz oy))
|
||||
dlen (math.sqrt (+ (* dx dx) (* dy dy) (* dz dz)))
|
||||
star-seed (pxl8.hash32 (+ STAR_SEED (* i 1000) (* (- j 1) 7)))
|
||||
color-type (% star-seed 6)
|
||||
glow (if (< color-type 2) GLOW_MAGIC GLOW_SILVER)
|
||||
is-anchor (and (= (- j 1) 0) (= i 11))]
|
||||
(table.insert stars {:dx (/ dx dlen) :dy (/ dy dlen) :dz (/ dz dlen)
|
||||
:brightness brightness
|
||||
:glow glow
|
||||
:is-anchor is-anchor})))))
|
||||
stars))
|
||||
|
||||
(fn generate-beacon-stars-data []
|
||||
(let [stars []
|
||||
seed (+ STAR_SEED 0xBEAC0000)]
|
||||
(for [i 0 (- NUM_BEACON_STARS 1)]
|
||||
(let [h1 (pxl8.hash32 (+ seed (* i 4)))
|
||||
h2 (pxl8.hash32 (+ seed (* i 4) 1))
|
||||
h3 (pxl8.hash32 (+ seed (* i 4) 2))
|
||||
theta (* (/ h1 0xFFFFFFFF) TAU)
|
||||
phi (+ 0.3 (* (/ h2 0xFFFFFFFF) 0.9))
|
||||
sin-phi (math.sin phi)
|
||||
x (* sin-phi (math.cos theta))
|
||||
y (math.cos phi)
|
||||
z (* sin-phi (math.sin theta))
|
||||
color-type (% h3 8)
|
||||
glow (if (< color-type 3) GLOW_MAGIC GLOW_SILVER)]
|
||||
(table.insert stars {:dx x :dy y :dz z :brightness 255 :glow glow})))
|
||||
stars))
|
||||
|
||||
(fn generate-random-stars-data []
|
||||
(let [stars []]
|
||||
(for [i 0 (- NUM_RANDOM_STARS 1)]
|
||||
(let [h1 (pxl8.hash32 (+ STAR_SEED (* i 5)))
|
||||
h2 (pxl8.hash32 (+ STAR_SEED (* i 5) 1))
|
||||
h3 (pxl8.hash32 (+ STAR_SEED (* i 5) 2))
|
||||
h4 (pxl8.hash32 (+ STAR_SEED (* i 5) 3))
|
||||
theta (* (/ h1 0xFFFFFFFF) TAU)
|
||||
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 0.85)))
|
||||
sin-phi (math.sin phi)
|
||||
dx (* sin-phi (math.cos theta))
|
||||
dy (math.cos phi)
|
||||
dz (* sin-phi (math.sin theta))
|
||||
brightness-raw (/ (% h3 256) 255)
|
||||
brightness (math.floor (+ 60 (* brightness-raw brightness-raw 140)))
|
||||
color-type (% h4 100)
|
||||
glow (if (< color-type 8) GLOW_TORCH
|
||||
(< color-type 16) GLOW_MAGIC
|
||||
GLOW_SILVER)]
|
||||
(when (> dy 0.05)
|
||||
(table.insert stars {:dx dx :dy dy :dz dz
|
||||
:brightness brightness :glow glow}))))
|
||||
stars))
|
||||
|
||||
(fn generate-tiny-stars-data []
|
||||
(let [stars []
|
||||
seed (+ STAR_SEED 0xCAFEBABE)]
|
||||
(for [i 0 (- NUM_TINY_STARS 1)]
|
||||
(let [h1 (pxl8.hash32 (+ seed (* i 4)))
|
||||
h2 (pxl8.hash32 (+ seed (* i 4) 1))
|
||||
h3 (pxl8.hash32 (+ seed (* i 4) 2))
|
||||
h4 (pxl8.hash32 (+ seed (* i 4) 3))
|
||||
theta (* (/ h1 0xFFFFFFFF) TAU)
|
||||
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 0.95)))
|
||||
sin-phi (math.sin phi)
|
||||
dx (* sin-phi (math.cos theta))
|
||||
dy (math.cos phi)
|
||||
dz (* sin-phi (math.sin theta))
|
||||
band-boost (galactic-band-factor dx dy dz)
|
||||
base-bright (+ 25 (% h3 40))
|
||||
brightness (+ base-bright (math.floor (* band-boost 35)))
|
||||
color-shift (% h4 100)
|
||||
glow (if (< color-shift 3) GLOW_TORCH
|
||||
(< color-shift 15) GLOW_MAGIC
|
||||
GLOW_SILVER)]
|
||||
(when (> dy -0.05)
|
||||
(table.insert stars {:dx dx :dy dy :dz dz
|
||||
:brightness brightness :glow glow}))))
|
||||
stars))
|
||||
|
||||
(fn pack-star-directions [stars idx]
|
||||
(var i idx)
|
||||
(each [_ star (ipairs stars)]
|
||||
(let [dir (. star-directions i)]
|
||||
(set dir.x star.dx)
|
||||
(set dir.y star.dy)
|
||||
(set dir.z star.dz))
|
||||
(set i (+ i 1)))
|
||||
i)
|
||||
|
||||
(fn generate-stars []
|
||||
(set tiny-stars (generate-tiny-stars-data))
|
||||
(set random-stars (generate-random-stars-data))
|
||||
(set constellation-stars (generate-constellation-stars-data))
|
||||
(set beacon-stars (generate-beacon-stars-data))
|
||||
|
||||
(set star-count (+ (# tiny-stars) (# random-stars)
|
||||
(# constellation-stars) (# beacon-stars)))
|
||||
(set star-directions (pxl8.create_vec3_array star-count))
|
||||
(when pxl8.create_glows
|
||||
(set star-glows (pxl8.create_glows 16384)))
|
||||
(set star-projected (pxl8.create_vec3_array star-count))
|
||||
(set celestial-directions (pxl8.create_vec3_array 2))
|
||||
(set celestial-projected (pxl8.create_vec3_array 2))
|
||||
(var idx 0)
|
||||
(set idx (pack-star-directions tiny-stars idx))
|
||||
(set idx (pack-star-directions random-stars idx))
|
||||
(set idx (pack-star-directions constellation-stars idx))
|
||||
(set idx (pack-star-directions beacon-stars idx)))
|
||||
|
||||
(fn star-brightness [time]
|
||||
(if (< time 0.18) 1.0
|
||||
(< time 0.26) (let [t (/ (- time 0.18) 0.08)
|
||||
ease (* t t (- 3.0 (* 2.0 t)))]
|
||||
(- 1.0 ease))
|
||||
(< time 0.74) 0.0
|
||||
(< time 0.82) (let [t (/ (- time 0.74) 0.08)
|
||||
ease (* t t (- 3.0 (* 2.0 t)))]
|
||||
ease)
|
||||
1.0))
|
||||
|
||||
(fn ease-celestial [t]
|
||||
(let [s (math.sin (* 2 t TAU))
|
||||
ease (/ (* 0.9 s) (* 2 TAU))]
|
||||
(- t ease)))
|
||||
|
||||
(fn sun-direction [time]
|
||||
(let [eased (ease-celestial time)
|
||||
angle (* (- eased 0.25) TAU)
|
||||
y (math.sin angle)
|
||||
xz (math.cos angle)
|
||||
sx (* xz 0.7)
|
||||
sz (* xz 0.7)
|
||||
len (math.sqrt (+ (* sx sx) (* y y) (* sz sz)))]
|
||||
(values (/ sx len) (/ y len) (/ sz len))))
|
||||
|
||||
(fn moon-direction [time]
|
||||
(let [eased (ease-celestial time)
|
||||
azimuth (* (- eased 0.75) TAU 0.5)
|
||||
elev (math.sin (* 25 (/ math.pi 180)))
|
||||
horiz (math.cos (* 25 (/ math.pi 180)))
|
||||
sx (* (- (math.cos azimuth)) horiz)
|
||||
sz (* (math.sin azimuth) horiz)]
|
||||
(values sx elev sz)))
|
||||
|
||||
(fn render-stars [cam-x cam-y cam-z time days dt]
|
||||
(set twinkle-time (+ twinkle-time (or dt 0)))
|
||||
(when (and (> star-count 0) star-glows)
|
||||
(let [time-val (or time 0)
|
||||
days-val (or days 0)
|
||||
star-bright (star-brightness time-val)
|
||||
fade-in (* star-bright star-bright)
|
||||
time-factor (/ twinkle-time 60)
|
||||
star-rotation (/ (* (+ days-val time-val) TAU) STAR_CYCLE_DAYS)
|
||||
t (pxl8.mat4_translate cam-x cam-y cam-z)
|
||||
r (pxl8.mat4_rotate_y star-rotation)
|
||||
s (pxl8.mat4_scale sky-radius sky-radius sky-radius)
|
||||
transform (pxl8.mat4_multiply t (pxl8.mat4_multiply r s))
|
||||
tiny-count (# tiny-stars)
|
||||
random-count (# random-stars)
|
||||
constellation-count (# constellation-stars)
|
||||
beacon-count (# beacon-stars)
|
||||
random-offset tiny-count
|
||||
constellation-offset (+ tiny-count random-count)
|
||||
beacon-offset (+ tiny-count random-count constellation-count)]
|
||||
|
||||
(star-glows:clear)
|
||||
(pxl8.project_points star-directions star-projected star-count transform)
|
||||
|
||||
(when (> star-bright 0.02)
|
||||
(for [i 0 (- tiny-count 1)]
|
||||
(let [screen (. star-projected i)]
|
||||
(when (> screen.z 0)
|
||||
(let [star (. tiny-stars (+ i 1))
|
||||
int (math.floor (* star.brightness fade-in))]
|
||||
(when (> int 8)
|
||||
(star-glows:add (math.floor (+ screen.x 0.5))
|
||||
(math.floor (+ screen.y 0.5))
|
||||
1 int star.glow pxl8.GLOW_CIRCLE))))))
|
||||
|
||||
(for [i 0 (- constellation-count 1)]
|
||||
(let [screen (. star-projected (+ constellation-offset i))]
|
||||
(when (> screen.z 0)
|
||||
(let [star (. constellation-stars (+ i 1))
|
||||
phase (+ (* i 1.618) (* time-val 2.5))
|
||||
twinkle (+ 0.85 (* 0.15 (math.sin (* phase 6.28))))
|
||||
int (math.floor (* star.brightness fade-in twinkle 1.5))
|
||||
sx (math.floor (+ screen.x 0.5))
|
||||
sy (math.floor (+ screen.y 0.5))]
|
||||
(if star.is-anchor
|
||||
(do
|
||||
(star-glows:add sx sy 4 (* int 2) star.glow pxl8.GLOW_CIRCLE)
|
||||
(star-glows:add sx sy 8 (math.floor (/ int 2)) star.glow pxl8.GLOW_CIRCLE))
|
||||
(> star.brightness 220)
|
||||
(do
|
||||
(star-glows:add sx sy 3 (math.floor (* int 1.5)) star.glow pxl8.GLOW_DIAMOND)
|
||||
(star-glows:add sx sy 5 (math.floor (/ int 2)) star.glow pxl8.GLOW_CIRCLE))
|
||||
(> star.brightness 180)
|
||||
(do
|
||||
(star-glows:add sx sy 2 int star.glow pxl8.GLOW_DIAMOND)
|
||||
(star-glows:add sx sy 4 (math.floor (/ int 3)) star.glow pxl8.GLOW_CIRCLE))
|
||||
(do
|
||||
(star-glows:add sx sy 2 (math.floor (/ (* int 2) 3)) star.glow pxl8.GLOW_DIAMOND)
|
||||
(star-glows:add sx sy 3 (math.floor (/ int 4)) star.glow pxl8.GLOW_CIRCLE)))))))
|
||||
|
||||
(for [i 0 (- beacon-count 1)]
|
||||
(let [screen (. star-projected (+ beacon-offset i))]
|
||||
(when (> screen.z 0)
|
||||
(let [star (. beacon-stars (+ i 1))
|
||||
phase (+ (* i 2.718) (* time-val 1.5))
|
||||
twinkle (+ 0.9 (* 0.1 (math.sin (* phase 6.28))))
|
||||
int (math.floor (* 400 fade-in twinkle))
|
||||
sx (math.floor (+ screen.x 0.5))
|
||||
sy (math.floor (+ screen.y 0.5))]
|
||||
(star-glows:add sx sy 4 int star.glow pxl8.GLOW_CIRCLE)
|
||||
(star-glows:add sx sy 7 (math.floor (/ int 3)) star.glow pxl8.GLOW_CIRCLE)))))
|
||||
|
||||
(for [i 0 (- random-count 1)]
|
||||
(let [screen (. star-projected (+ random-offset i))]
|
||||
(when (> screen.z 0)
|
||||
(let [star (. random-stars (+ i 1))
|
||||
phase (+ (* i 2.137) (* time-factor 3.0))
|
||||
twinkle (+ 0.75 (* 0.25 (math.sin (* phase 6.28))))
|
||||
int (math.floor (* star.brightness fade-in twinkle))
|
||||
sx (math.floor (+ screen.x 0.5))
|
||||
sy (math.floor (+ screen.y 0.5))]
|
||||
(when (> star.brightness 180)
|
||||
(star-glows:add sx sy 2 (math.floor (* int 1.5)) star.glow pxl8.GLOW_CIRCLE))
|
||||
(when (and (<= star.brightness 180) (> star.brightness 120))
|
||||
(star-glows:add sx sy 2 int star.glow pxl8.GLOW_CIRCLE)))))))
|
||||
|
||||
(let [(sun-dx sun-dy sun-dz) (sun-direction time-val)]
|
||||
(when (> sun-dy 0)
|
||||
(let [dir (. celestial-directions 0)]
|
||||
(set dir.x sun-dx)
|
||||
(set dir.y sun-dy)
|
||||
(set dir.z sun-dz))
|
||||
(let [ct (pxl8.mat4_translate cam-x cam-y cam-z)
|
||||
cs (pxl8.mat4_scale sky-radius sky-radius sky-radius)
|
||||
cel-transform (pxl8.mat4_multiply ct cs)]
|
||||
(pxl8.project_points celestial-directions celestial-projected 1 cel-transform)
|
||||
(let [screen (. celestial-projected 0)]
|
||||
(when (> screen.z 0)
|
||||
(let [sx (math.floor (+ screen.x 0.5))
|
||||
sy (math.floor (+ screen.y 0.5))
|
||||
horizon-factor (- 1 sun-dy)
|
||||
size-scale (+ 1 (* horizon-factor 0.6))
|
||||
r-outer (math.floor (* 50 size-scale))
|
||||
r-mid (math.floor (* 38 size-scale))
|
||||
r-inner (math.floor (* 26 size-scale))]
|
||||
(star-glows:add sx sy r-outer 80 GLOW_CRIMSON pxl8.GLOW_CIRCLE 0)
|
||||
(star-glows:add sx sy r-mid 180 GLOW_CRIMSON pxl8.GLOW_CIRCLE 0)
|
||||
(star-glows:add sx sy r-inner 255 GLOW_TORCH pxl8.GLOW_CIRCLE 0)))))))
|
||||
|
||||
(when (> star-bright 0.02)
|
||||
(let [(moon-dx moon-dy moon-dz) (moon-direction time-val)]
|
||||
(when (> moon-dy 0)
|
||||
(let [dir (. celestial-directions 1)]
|
||||
(set dir.x moon-dx)
|
||||
(set dir.y moon-dy)
|
||||
(set dir.z moon-dz))
|
||||
(let [ct (pxl8.mat4_translate cam-x cam-y cam-z)
|
||||
cs (pxl8.mat4_scale sky-radius sky-radius sky-radius)
|
||||
cel-transform (pxl8.mat4_multiply ct cs)]
|
||||
(pxl8.project_points celestial-directions celestial-projected 2 cel-transform)
|
||||
(let [screen (. celestial-projected 1)]
|
||||
(when (> screen.z 0)
|
||||
(let [sx (math.floor (+ screen.x 0.5))
|
||||
sy (math.floor (+ screen.y 0.5))]
|
||||
(star-glows:add sx sy 6 (math.floor (* 500 fade-in)) GLOW_SILVER pxl8.GLOW_DIAMOND)
|
||||
(star-glows:add sx sy 10 (math.floor (* 200 fade-in)) GLOW_SILVER pxl8.GLOW_CIRCLE)
|
||||
(star-glows:add sx sy 16 (math.floor (* 60 fade-in)) GLOW_DEEP_BLUE pxl8.GLOW_CIRCLE))))))))
|
||||
|
||||
|
||||
|
||||
(when (> (star-glows:count) 0)
|
||||
(star-glows:render)))))
|
||||
|
||||
(fn render [cam-x cam-y cam-z wireframe]
|
||||
(when (not sky-mesh) (create-sky-dome))
|
||||
(when sky-mesh
|
||||
(pxl8.draw_mesh sky-mesh {:x cam-x :y cam-y :z cam-z :wireframe wireframe})))
|
||||
|
||||
{:render render
|
||||
:render-stars render-stars
|
||||
:generate-stars generate-stars
|
||||
:reset-gradient reset-gradient
|
||||
:update-gradient update-gradient
|
||||
:star-brightness star-brightness
|
||||
:ease-celestial ease-celestial
|
||||
:sun-direction sun-direction
|
||||
:moon-direction moon-direction
|
||||
:SKY_GRADIENT_START SKY_GRADIENT_START
|
||||
:SKY_GRADIENT_COUNT SKY_GRADIENT_COUNT}
|
||||
|
|
@ -1,384 +0,0 @@
|
|||
(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)))
|
||||
|
||||
(fn textures.rough-stone [seed base-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [cell (voronoi-cell ctx 8)
|
||||
edge (voronoi-edge ctx 8)
|
||||
crack-threshold (const ctx 0.03)
|
||||
is-crack (sub ctx crack-threshold edge)
|
||||
crack-color (const ctx (- base-color 3))
|
||||
roughness (noise-turbulence ctx 3 24 0.6)
|
||||
detail (noise-value ctx 48)
|
||||
combined (add ctx (mul ctx roughness (const ctx 0.5))
|
||||
(add ctx (mul ctx cell (const ctx 0.3))
|
||||
(mul ctx detail (const ctx 0.2))))
|
||||
stone-quant (quantize ctx combined base-color 6)]
|
||||
(select ctx is-crack crack-color stone-quant))))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
(fn textures.packed-dirt [seed base-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [base-noise (noise-fbm ctx 3 16 0.5)
|
||||
detail (noise-value ctx 32)
|
||||
combined (add ctx (mul ctx base-noise (const ctx 0.6))
|
||||
(mul ctx detail (const ctx 0.4)))
|
||||
dirt-quant (quantize ctx combined base-color 5)
|
||||
pebble (voronoi-cell ctx 12)
|
||||
pebble-edge (voronoi-edge ctx 12)
|
||||
pebble-threshold (const ctx 0.08)
|
||||
is-pebble (sub ctx pebble-threshold pebble-edge)
|
||||
pebble-quant (quantize ctx pebble (- base-color 2) 4)]
|
||||
(select ctx is-pebble pebble-quant dirt-quant))))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
(fn textures.grass-top [seed base-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [blade-x (mul ctx ctx.x (const ctx 32))
|
||||
blade-y (mul ctx ctx.y (const ctx 4))
|
||||
blades (noise-fbm-at ctx blade-x blade-y 3 6 0.5)
|
||||
fine (noise-value ctx 64)
|
||||
patch (noise-fbm ctx 2 6 0.4)
|
||||
combined (add ctx (mul ctx blades (const ctx 0.4))
|
||||
(add ctx (mul ctx fine (const ctx 0.3))
|
||||
(mul ctx patch (const ctx 0.3))))
|
||||
grass-quant (quantize ctx combined base-color 6)]
|
||||
grass-quant)))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
textures
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
(local vfx {})
|
||||
|
||||
(fn vfx.explosion [ps x y ?opts]
|
||||
(let [opts (or ?opts {})
|
||||
color (or opts.color 208)
|
||||
force (or opts.force 200)]
|
||||
(ps:set_position x y)
|
||||
(ps:set_colors color (+ color 15))
|
||||
(ps:set_velocity (- force) force (- force) force)
|
||||
(ps:set_gravity 0 100)
|
||||
(ps:set_life 0.3 0.8)
|
||||
(ps:set_size 1 3)
|
||||
(ps:set_drag 0.98)
|
||||
(ps:set_spawn_rate 0)
|
||||
(ps:emit (or opts.count 50))))
|
||||
|
||||
(fn vfx.fire [ps x y ?opts]
|
||||
(let [opts (or ?opts {})
|
||||
width (or opts.width 50)
|
||||
color (or opts.color 208)]
|
||||
(ps:set_position x y)
|
||||
(ps:set_spread width 5)
|
||||
(ps:set_colors color (+ color 15))
|
||||
(ps:set_velocity -20 20 -80 -40)
|
||||
(ps:set_gravity 0 -30)
|
||||
(ps:set_life 0.5 1.5)
|
||||
(ps:set_size 1 2)
|
||||
(ps:set_turbulence 30)
|
||||
(ps:set_drag 0.95)
|
||||
(ps:set_spawn_rate (or opts.rate 50))))
|
||||
|
||||
(fn vfx.rain [ps width ?opts]
|
||||
(let [opts (or ?opts {})
|
||||
wind (or opts.wind 0)
|
||||
color (or opts.color 153)]
|
||||
(ps:set_position (/ width 2) -10)
|
||||
(ps:set_spread width 0)
|
||||
(ps:set_colors color (+ color 3))
|
||||
(ps:set_velocity (- wind 10) (+ wind 10) 300 400)
|
||||
(ps:set_gravity 0 200)
|
||||
(ps:set_life 1 2)
|
||||
(ps:set_size 1 1)
|
||||
(ps:set_drag 1)
|
||||
(ps:set_spawn_rate (or opts.rate 100))))
|
||||
|
||||
(fn vfx.smoke [ps x y ?opts]
|
||||
(let [opts (or ?opts {})
|
||||
color (or opts.color 248)]
|
||||
(ps:set_position x y)
|
||||
(ps:set_spread 10 5)
|
||||
(ps:set_colors color (+ color 7))
|
||||
(ps:set_velocity -15 15 -30 -10)
|
||||
(ps:set_gravity 0 -20)
|
||||
(ps:set_life 1 3)
|
||||
(ps:set_size 2 4)
|
||||
(ps:set_turbulence 20)
|
||||
(ps:set_drag 0.98)
|
||||
(ps:set_spawn_rate (or opts.rate 20))))
|
||||
|
||||
(fn vfx.snow [ps width ?opts]
|
||||
(let [opts (or ?opts {})
|
||||
wind (or opts.wind 10)
|
||||
color (or opts.color 15)]
|
||||
(ps:set_position (/ width 2) -10)
|
||||
(ps:set_spread width 0)
|
||||
(ps:set_colors color color)
|
||||
(ps:set_velocity (- wind 20) (+ wind 20) 30 60)
|
||||
(ps:set_gravity 0 10)
|
||||
(ps:set_life 3 6)
|
||||
(ps:set_size 1 2)
|
||||
(ps:set_turbulence 15)
|
||||
(ps:set_drag 0.99)
|
||||
(ps:set_spawn_rate (or opts.rate 30))))
|
||||
|
||||
vfx
|
||||
Loading…
Add table
Add a link
Reference in a new issue