glow rendering fixes to bring stars back

This commit is contained in:
asrael 2026-02-10 11:10:37 -06:00
parent 657b590b6f
commit c538641ec8
26 changed files with 773 additions and 1491 deletions

File diff suppressed because it is too large Load diff

View file

@ -10,17 +10,19 @@
(var door-tex nil)
(var fireball-mesh nil)
(fn create-door-mesh []
(fn create-door-mesh [bsp ambient]
(let [verts []
indices []
hw (/ DOOR_WIDTH 2)
y0 0
y1 DOOR_HEIGHT
x DOOR_X]
(table.insert verts {:x x :y y0 :z (- DOOR_Z hw) :u 0 :v 1 :nx -1 :ny 0 :nz 0 :color 80 :light 200})
(table.insert verts {:x x :y y0 :z (+ DOOR_Z hw) :u 1 :v 1 :nx -1 :ny 0 :nz 0 :color 80 :light 200})
(table.insert verts {:x x :y y1 :z (+ DOOR_Z hw) :u 1 :v 0 :nx -1 :ny 0 :nz 0 :color 80 :light 200})
(table.insert verts {:x x :y y1 :z (- DOOR_Z hw) :u 0 :v 0 :nx -1 :ny 0 :nz 0 :color 80 :light 200})
x DOOR_X
sample (fn [vx vy vz]
(if bsp (bsp:light_at vx vy vz (or ambient 0)) 200))]
(table.insert verts {:x x :y y0 :z (- DOOR_Z hw) :u 0 :v 1 :nx -1 :ny 0 :nz 0 :color 80 :light (sample x y0 (- DOOR_Z hw))})
(table.insert verts {:x x :y y0 :z (+ DOOR_Z hw) :u 1 :v 1 :nx -1 :ny 0 :nz 0 :color 80 :light (sample x y0 (+ DOOR_Z hw))})
(table.insert verts {:x x :y y1 :z (+ DOOR_Z hw) :u 1 :v 0 :nx -1 :ny 0 :nz 0 :color 80 :light (sample x y1 (+ DOOR_Z hw))})
(table.insert verts {:x x :y y1 :z (- DOOR_Z hw) :u 0 :v 0 :nx -1 :ny 0 :nz 0 :color 80 :light (sample x y1 (- DOOR_Z hw))})
(table.insert indices 0)
(table.insert indices 1)
(table.insert indices 2)
@ -150,13 +152,15 @@
20)
(fn init [textures]
(when (not door-mesh)
(create-door-mesh))
(when (not fireball-mesh)
(create-fireball-mesh))
(when (and (not door-tex) textures)
(set door-tex (textures.door))))
(fn setup-lighting [bsp ambient]
(when (and (not door-mesh) bsp)
(create-door-mesh bsp ambient)))
(fn render-door [wireframe floor-y]
(when (and door-mesh door-tex)
(pxl8.draw_mesh door-mesh {:x 0 :y (or floor-y 0) :z 0
@ -176,4 +180,5 @@
:get-door-radius get-door-radius
:init init
:render-door render-door
:render-fireball render-fireball}
:render-fireball render-fireball
:setup-lighting setup-lighting}

View file

@ -2,10 +2,8 @@
(local effects (require :pxl8.effects))
(local net (require :pxl8.net))
(local colormap (require :mod.colormap))
(local entities (require :mod.entities))
(local menu (require :mod.menu))
(local palette (require :mod.palette))
(local sky (require :mod.sky))
(local textures (require :mod.textures))
@ -26,14 +24,16 @@
(local player-height 72)
(local player-radius 12)
(local step-height 24)
(local day-length 1800)
(local turn-speed 4.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-y 600)
(var cam-yaw 0)
(var cam-z 416)
(var camera nil)
@ -43,6 +43,7 @@
(var land-squash 0)
(var last-dt 0.016)
(var light-time 0)
(var glows nil)
(var lights nil)
(var bsp-materials-setup false)
(var network nil)
@ -102,8 +103,7 @@
(fn init []
(pxl8.set_relative_mouse_mode true)
(pxl8.set_palette palette 256)
(pxl8.set_colormap colormap 16384)
(pxl8.load_palette "res/palettes/palette.ase")
(for [i 0 7]
(let [t (/ i 7)
r 0xFF
@ -117,6 +117,8 @@
(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)))
@ -143,6 +145,7 @@
(world:set_bsp_material 0 floor-mat)
(world:set_bsp_material 1 wall-mat)
(world:set_bsp_material 3 trim-mat)
(entities.setup-lighting (chunk:bsp) 2)
(set bsp-materials-setup true))))))
(fn sample-input []
@ -194,7 +197,7 @@
(pxl8.info "Exiting through door...")
(let [exit-x (+ door-x 50)
exit-z door-z
exit-y 200]
exit-y 600]
(network:exit_chunk exit-x exit-y exit-z)
(set cam-x exit-x)
(set cam-z exit-z)
@ -287,6 +290,7 @@
(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))))))
@ -345,14 +349,13 @@
(pxl8.begin_frame_3d camera lights {
:ambient 2
:dither true
:fog_density 0.0
:fog_density 0.002
:celestial_dir [0.5 -0.8 0.3]
:celestial_intensity 0.3})
(pxl8.clear_depth)
(sky.update-gradient 1 2 6 6 10 18)
(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))
(sky.render-stars smooth-cam-x eye-y smooth-cam-z 1.0 last-dt)
(pxl8.clear_depth)
(pxl8.set_wireframe (menu.is-wireframe))
@ -364,6 +367,10 @@
(entities.render-door (menu.is-wireframe) (if voxel-space 128 0))
(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)

View file

@ -1,263 +0,0 @@
(require :pxl8)
(local ffi (require :ffi))
(local data (ffi.new "u32[256]" [
0x080602
0x14120E
0x23211E
0x31302C
0x403E3B
0x4B4946
0x595755
0x676664
0x767573
0x858382
0x939290
0xA2A09F
0xB0AFAE
0xBEBDBC
0xCDCCCC
0xDADAD9
0x594625
0x544023
0x4F3C24
0x4C3A22
0x453821
0x40321F
0x3E2F20
0x382D1D
0x33291E
0x30271F
0x2F251D
0x2D231E
0x28211C
0x251F1D
0x23201A
0x221F1B
0x646269
0x5F5C61
0x5C545A
0x584F55
0x5B514F
0x554A47
0x4B413F
0x423C36
0x463D31
0x3E352A
0x362E25
0x2D2922
0x26221D
0x1C1916
0x151310
0x100F0D
0x8C6F52
0x7E6045
0x73553B
0x715134
0xBA8346
0xA1723B
0x815C2E
0x745226
0xCC8926
0xBB7E22
0x9F6B1F
0x875A1C
0x6E4918
0x553712
0x3B250D
0x24180A
0xA34331
0x9B3728
0x923220
0x882E18
0x842B16
0x772312
0x69200D
0x5A1C06
0x541C04
0x4C1A03
0x411701
0x371000
0x2E0D00
0x250B00
0x1B0600
0x130500
0x7D5741
0x76503A
0x6E4C37
0x684833
0x5D3F2F
0x553A2C
0x4F3628
0x483024
0x4A3126
0x483025
0x432D22
0x3C2C22
0x352922
0x2C241F
0x221C1B
0x1A1916
0x6E4626
0x5F4025
0x523924
0x433322
0x352B1E
0x28231A
0x1A1A14
0x1C1815
0x96544B
0xAC7369
0xB48C86
0xBCA7A4
0xB1BCC2
0x9DB0B9
0x8A9FAA
0x77929F
0x738995
0x5E7C8B
0x4A6C7D
0x345E72
0x1F4C64
0x19445C
0x143C51
0x10384B
0x183748
0x1A3341
0x192F39
0x152B34
0x13262E
0x101E23
0x0E1519
0x0B0E10
0x896463
0x815C5B
0x785352
0x6F4C4D
0x664444
0x5F3C3D
0x573738
0x523233
0x442929
0x392324
0x2D1D1D
0x241414
0x1A0E0E
0x100909
0x070403
0x000000
0x98936F
0x918B68
0x887F60
0x807759
0x797055
0x73684D
0x6B6146
0x63593F
0x5B523A
0x504834
0x423D2D
0x373226
0x2E2B1F
0x222018
0x161511
0x0E0F0A
0x9A554F
0x904D48
0x87453F
0x7D4037
0x743831
0x693329
0x612C24
0x572720
0x4F231A
0x441E16
0x391914
0x2D150F
0x22110D
0x1A0B06
0x0D0403
0x040202
0x7F77C0
0x7770B5
0x6E68A8
0x686099
0x60588C
0x575381
0x4E4C72
0x454263
0x3D3957
0x34324A
0x2C2940
0x242135
0x1E1928
0x16121D
0x0C0A12
0x050306
0x88AF7B
0x81A473
0x7B9A67
0x728E5D
0x6D8553
0x61794A
0x5B7144
0x61734B
0x586A3D
0x4D5E2D
0x465422
0x3F4D17
0x36420E
0x2F3507
0x272804
0x211F02
0x1EF708
0x3CE10D
0x51CC1B
0x64B621
0x6DA12C
0x69882B
0x727F3B
0xE4DDCE
0xEEE6BA
0xEAE290
0xE9E26D
0xE5DE43
0xE3DB20
0xE1CC18
0xDFB911
0xDCA60B
0xE8A306
0xDF9312
0xE17B05
0xC86815
0xBC5908
0xB14805
0xA63D07
0xB6431E
0xAA381A
0x9A2E12
0x8C270F
0x892B17
0x762311
0x5F1F0D
0x491B09
0x3B1809
0xE50F19
0x6A34C4
0xE00B28
0x2B08C8
0x322A33
0x281C0E
0x2F1E15
0xD48067
0xC26B4C
0x974928
0x814123
0xD5B3A9
0xBE9D93
0x9A7B6C
0x7F5F51
0x8E504C
]))
data

View file

@ -8,17 +8,60 @@
(local NUM_RANDOM_STARS 300)
(local NUM_TINY_STARS 7000)
(local STAR_CYCLE_PERIOD 86400)
(local NUM_BEACON_STARS 8)
(local STAR_SEED 0xDEADBEEF)
(local STAR_CYCLE_DAYS 90)
(local TAU (* math.pi 2))
;; Use existing bright palette colors
;; Silver/white: indices 14-15 (brightest grays)
(local IDX_SILVER 14)
;; Warm/torch: indices 216-218 (bright creams/yellows)
(local IDX_TORCH 216)
;; Blue/magic: indices 176-178 (purples - brightest of the range)
(local IDX_MAGIC 176)
(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)
@ -26,8 +69,8 @@
(var star-directions nil)
(var star-glows nil)
(var star-projected nil)
(var star-time 0)
(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)]
@ -105,142 +148,341 @@
(generate-sky-gradient zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b)
(set last-gradient-key key))))
(fn band-factor [dx dy dz bx by bz width]
(let [dist (math.abs (+ (* dx bx) (* dy by) (* dz bz)))
in-band (- 1 (math.min (* dist width) 1))]
(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 galactic-band-factor [dx dy dz]
(let [;; Main galactic band - crosses zenith
band-len (math.sqrt (+ (* 0.6 0.6) (* 0.3 0.3) (* 0.742 0.742)))
b1 (band-factor dx dy dz (/ 0.6 band-len) (/ 0.3 band-len) (/ 0.742 band-len) 3)
;; Secondary band - lower angle, different orientation
b2 (band-factor dx dy dz 0.8 0.15 0.58 3.5)
;; Tertiary band - opposite side
b3 (band-factor dx dy dz -0.7 0.2 0.69 4)]
(math.max b1 b2 b3)))
(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-stars []
(set random-stars [])
(set tiny-stars [])
;; Generate random stars - use full upper hemisphere (dy > -0.1)
(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) math.pi 2)
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0)))
sin-phi (math.sin phi)
cos-phi (math.cos phi)
dx (* sin-phi (math.cos theta))
dy cos-phi
dz (* sin-phi (math.sin theta))
brightness-raw (/ (% h3 256) 255)
brightness (math.floor (+ 60 (* brightness-raw brightness-raw 195)))
color-type (% h4 100)
color (if (< color-type 8) (+ IDX_TORCH (% (bit.rshift h4 8) 2))
(< color-type 16) (+ IDX_MAGIC (% (bit.rshift h4 8) 2))
(+ IDX_SILVER (% (bit.rshift h4 8) 2)))]
(when (> dy -0.1)
(table.insert random-stars {:dx dx :dy dy :dz dz
:brightness brightness
:color color}))))
(let [tiny-seed (+ STAR_SEED 0xCAFEBABE)]
(for [i 0 (- NUM_TINY_STARS 1)]
(let [h1 (pxl8.hash32 (+ tiny-seed (* i 4)))
h2 (pxl8.hash32 (+ tiny-seed (* i 4) 1))
h3 (pxl8.hash32 (+ tiny-seed (* i 4) 2))
h4 (pxl8.hash32 (+ tiny-seed (* i 4) 3))
theta (* (/ h1 0xFFFFFFFF) math.pi 2)
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0)))
(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)
cos-phi (math.cos phi)
dx (* sin-phi (math.cos theta))
dy cos-phi
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 (+ 40 (% h3 50))
brightness (+ base-bright (math.floor (* band-boost 40)))
base-bright (+ 25 (% h3 40))
brightness (+ base-bright (math.floor (* band-boost 35)))
color-shift (% h4 100)
color (if (< color-shift 3) (+ IDX_TORCH (% (bit.rshift h4 8) 2))
(< color-shift 12) (+ IDX_MAGIC (% (bit.rshift h4 8) 2))
(+ IDX_SILVER (% (bit.rshift h4 8) 2)))]
(when (> dy -0.1)
(table.insert tiny-stars {:dx dx :dy dy :dz dz
:brightness brightness
:color color})))))
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))
(set star-count (+ (length tiny-stars) (length random-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 10000)))
(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)
(each [_ star (ipairs tiny-stars)]
(let [dir (. star-directions idx)]
(set dir.x star.dx)
(set dir.y star.dy)
(set dir.z star.dz))
(set idx (+ idx 1)))
(each [_ star (ipairs random-stars)]
(let [dir (. star-directions idx)]
(set dir.x star.dx)
(set dir.y star.dy)
(set dir.z star.dz))
(set idx (+ idx 1))))
(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 render-stars [cam-x cam-y cam-z intensity dt]
(set star-time (+ star-time (or dt 0)))
(when (and (> intensity 0) (> star-count 0) star-glows)
(let [fade-in (* intensity intensity)
time-factor (/ star-time 60)
star-rotation (/ (* star-time math.pi 2) STAR_CYCLE_PERIOD)
(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 (length tiny-stars)]
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)
(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)
(let [px (math.floor (+ screen.x 0.5))
py (math.floor (+ screen.y 0.5))]
(star-glows:add px py 1 int star.color pxl8.GLOW_CIRCLE)))))))
(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))))))))
(for [i 0 (- (length random-stars) 1)]
(let [screen (. star-projected (+ tiny-count i))]
(when (> screen.z 0)
(let [star (. random-stars (+ i 1))
phase (+ (* (+ i 1) 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))]
(if (> star.brightness 220)
(do
(star-glows:add sx sy 3 (math.floor (* int 1.5)) star.color pxl8.GLOW_DIAMOND)
(star-glows:add sx sy 5 (math.floor (/ int 2)) star.color pxl8.GLOW_CIRCLE))
(> star.brightness 180)
(do
(star-glows:add sx sy 2 int star.color pxl8.GLOW_DIAMOND)
(star-glows:add sx sy 4 (math.floor (/ int 3)) star.color pxl8.GLOW_CIRCLE))
(> star.brightness 120)
(do
(star-glows:add sx sy 2 (math.floor (* int 0.67)) star.color pxl8.GLOW_DIAMOND)
(star-glows:add sx sy 3 (math.floor (/ int 4)) star.color pxl8.GLOW_CIRCLE))
(star-glows:add sx sy 2 (math.floor (* int 0.5)) star.color pxl8.GLOW_CIRCLE))))))
(when (> (star-glows:count) 0)
(star-glows:render)))))
@ -255,5 +497,9 @@
: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}