glow rendering fixes to bring stars back
This commit is contained in:
parent
657b590b6f
commit
c538641ec8
26 changed files with 773 additions and 1491 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -10,17 +10,19 @@
|
||||||
(var door-tex nil)
|
(var door-tex nil)
|
||||||
(var fireball-mesh nil)
|
(var fireball-mesh nil)
|
||||||
|
|
||||||
(fn create-door-mesh []
|
(fn create-door-mesh [bsp ambient]
|
||||||
(let [verts []
|
(let [verts []
|
||||||
indices []
|
indices []
|
||||||
hw (/ DOOR_WIDTH 2)
|
hw (/ DOOR_WIDTH 2)
|
||||||
y0 0
|
y0 0
|
||||||
y1 DOOR_HEIGHT
|
y1 DOOR_HEIGHT
|
||||||
x DOOR_X]
|
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})
|
sample (fn [vx vy vz]
|
||||||
(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})
|
(if bsp (bsp:light_at vx vy vz (or ambient 0)) 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 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 y1 :z (- DOOR_Z hw) :u 0 :v 0 :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 (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 0)
|
||||||
(table.insert indices 1)
|
(table.insert indices 1)
|
||||||
(table.insert indices 2)
|
(table.insert indices 2)
|
||||||
|
|
@ -150,13 +152,15 @@
|
||||||
20)
|
20)
|
||||||
|
|
||||||
(fn init [textures]
|
(fn init [textures]
|
||||||
(when (not door-mesh)
|
|
||||||
(create-door-mesh))
|
|
||||||
(when (not fireball-mesh)
|
(when (not fireball-mesh)
|
||||||
(create-fireball-mesh))
|
(create-fireball-mesh))
|
||||||
(when (and (not door-tex) textures)
|
(when (and (not door-tex) textures)
|
||||||
(set door-tex (textures.door))))
|
(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]
|
(fn render-door [wireframe floor-y]
|
||||||
(when (and door-mesh door-tex)
|
(when (and door-mesh door-tex)
|
||||||
(pxl8.draw_mesh door-mesh {:x 0 :y (or floor-y 0) :z 0
|
(pxl8.draw_mesh door-mesh {:x 0 :y (or floor-y 0) :z 0
|
||||||
|
|
@ -176,4 +180,5 @@
|
||||||
:get-door-radius get-door-radius
|
:get-door-radius get-door-radius
|
||||||
:init init
|
:init init
|
||||||
:render-door render-door
|
:render-door render-door
|
||||||
:render-fireball render-fireball}
|
:render-fireball render-fireball
|
||||||
|
:setup-lighting setup-lighting}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,8 @@
|
||||||
(local effects (require :pxl8.effects))
|
(local effects (require :pxl8.effects))
|
||||||
(local net (require :pxl8.net))
|
(local net (require :pxl8.net))
|
||||||
|
|
||||||
(local colormap (require :mod.colormap))
|
|
||||||
(local entities (require :mod.entities))
|
(local entities (require :mod.entities))
|
||||||
(local menu (require :mod.menu))
|
(local menu (require :mod.menu))
|
||||||
(local palette (require :mod.palette))
|
|
||||||
(local sky (require :mod.sky))
|
(local sky (require :mod.sky))
|
||||||
(local textures (require :mod.textures))
|
(local textures (require :mod.textures))
|
||||||
|
|
||||||
|
|
@ -26,14 +24,16 @@
|
||||||
(local player-height 72)
|
(local player-height 72)
|
||||||
(local player-radius 12)
|
(local player-radius 12)
|
||||||
(local step-height 24)
|
(local step-height 24)
|
||||||
|
(local day-length 1800)
|
||||||
(local turn-speed 4.0)
|
(local turn-speed 4.0)
|
||||||
|
|
||||||
(var auto-run-cancel-key nil)
|
(var auto-run-cancel-key nil)
|
||||||
(var auto-run? false)
|
(var auto-run? false)
|
||||||
(var bob-time 0)
|
(var bob-time 0)
|
||||||
(var cam-pitch 0)
|
(var cam-pitch 0)
|
||||||
|
(var day-time 0)
|
||||||
(var cam-x 416)
|
(var cam-x 416)
|
||||||
(var cam-y 0)
|
(var cam-y 600)
|
||||||
(var cam-yaw 0)
|
(var cam-yaw 0)
|
||||||
(var cam-z 416)
|
(var cam-z 416)
|
||||||
(var camera nil)
|
(var camera nil)
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
(var land-squash 0)
|
(var land-squash 0)
|
||||||
(var last-dt 0.016)
|
(var last-dt 0.016)
|
||||||
(var light-time 0)
|
(var light-time 0)
|
||||||
|
(var glows nil)
|
||||||
(var lights nil)
|
(var lights nil)
|
||||||
(var bsp-materials-setup false)
|
(var bsp-materials-setup false)
|
||||||
(var network nil)
|
(var network nil)
|
||||||
|
|
@ -102,8 +103,7 @@
|
||||||
|
|
||||||
(fn init []
|
(fn init []
|
||||||
(pxl8.set_relative_mouse_mode true)
|
(pxl8.set_relative_mouse_mode true)
|
||||||
(pxl8.set_palette palette 256)
|
(pxl8.load_palette "res/palettes/palette.ase")
|
||||||
(pxl8.set_colormap colormap 16384)
|
|
||||||
(for [i 0 7]
|
(for [i 0 7]
|
||||||
(let [t (/ i 7)
|
(let [t (/ i 7)
|
||||||
r 0xFF
|
r 0xFF
|
||||||
|
|
@ -117,6 +117,8 @@
|
||||||
|
|
||||||
(when (not camera)
|
(when (not camera)
|
||||||
(set camera (pxl8.create_camera_3d)))
|
(set camera (pxl8.create_camera_3d)))
|
||||||
|
(when (not glows)
|
||||||
|
(set glows (pxl8.create_glows)))
|
||||||
(when (not lights)
|
(when (not lights)
|
||||||
(set lights (pxl8.create_lights)))
|
(set lights (pxl8.create_lights)))
|
||||||
|
|
||||||
|
|
@ -143,6 +145,7 @@
|
||||||
(world:set_bsp_material 0 floor-mat)
|
(world:set_bsp_material 0 floor-mat)
|
||||||
(world:set_bsp_material 1 wall-mat)
|
(world:set_bsp_material 1 wall-mat)
|
||||||
(world:set_bsp_material 3 trim-mat)
|
(world:set_bsp_material 3 trim-mat)
|
||||||
|
(entities.setup-lighting (chunk:bsp) 2)
|
||||||
(set bsp-materials-setup true))))))
|
(set bsp-materials-setup true))))))
|
||||||
|
|
||||||
(fn sample-input []
|
(fn sample-input []
|
||||||
|
|
@ -194,7 +197,7 @@
|
||||||
(pxl8.info "Exiting through door...")
|
(pxl8.info "Exiting through door...")
|
||||||
(let [exit-x (+ door-x 50)
|
(let [exit-x (+ door-x 50)
|
||||||
exit-z door-z
|
exit-z door-z
|
||||||
exit-y 200]
|
exit-y 600]
|
||||||
(network:exit_chunk exit-x exit-y exit-z)
|
(network:exit_chunk exit-x exit-y exit-z)
|
||||||
(set cam-x exit-x)
|
(set cam-x exit-x)
|
||||||
(set cam-z exit-z)
|
(set cam-z exit-z)
|
||||||
|
|
@ -287,6 +290,7 @@
|
||||||
(let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)]
|
(let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)]
|
||||||
(set bob-time (+ (* bob-time 0.8) (* target-phase 0.2))))))
|
(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 light-time (+ light-time (* dt 0.5)))
|
||||||
(set real-time (+ real-time dt))))))
|
(set real-time (+ real-time dt))))))
|
||||||
|
|
||||||
|
|
@ -345,14 +349,13 @@
|
||||||
(pxl8.begin_frame_3d camera lights {
|
(pxl8.begin_frame_3d camera lights {
|
||||||
:ambient 2
|
:ambient 2
|
||||||
:dither true
|
:dither true
|
||||||
:fog_density 0.0
|
:fog_density 0.002
|
||||||
:celestial_dir [0.5 -0.8 0.3]
|
:celestial_dir [0.5 -0.8 0.3]
|
||||||
:celestial_intensity 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 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.clear_depth)
|
||||||
|
|
||||||
(pxl8.set_wireframe (menu.is-wireframe))
|
(pxl8.set_wireframe (menu.is-wireframe))
|
||||||
|
|
@ -364,6 +367,10 @@
|
||||||
(entities.render-door (menu.is-wireframe) (if voxel-space 128 0))
|
(entities.render-door (menu.is-wireframe) (if voxel-space 128 0))
|
||||||
|
|
||||||
(pxl8.end_frame_3d)
|
(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.pop_target))
|
||||||
|
|
||||||
(pxl8.push_target)
|
(pxl8.push_target)
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
490
demo/mod/sky.fnl
490
demo/mod/sky.fnl
|
|
@ -8,17 +8,60 @@
|
||||||
|
|
||||||
(local NUM_RANDOM_STARS 300)
|
(local NUM_RANDOM_STARS 300)
|
||||||
(local NUM_TINY_STARS 7000)
|
(local NUM_TINY_STARS 7000)
|
||||||
(local STAR_CYCLE_PERIOD 86400)
|
(local NUM_BEACON_STARS 8)
|
||||||
(local STAR_SEED 0xDEADBEEF)
|
(local STAR_SEED 0xDEADBEEF)
|
||||||
|
(local STAR_CYCLE_DAYS 90)
|
||||||
|
(local TAU (* math.pi 2))
|
||||||
|
|
||||||
;; Use existing bright palette colors
|
(local GLOW_TORCH pxl8.LIGHT_ORANGE)
|
||||||
;; Silver/white: indices 14-15 (brightest grays)
|
(local GLOW_MAGIC pxl8.LIGHT_PURPLE)
|
||||||
(local IDX_SILVER 14)
|
(local GLOW_SILVER pxl8.LIGHT_WHITE)
|
||||||
;; Warm/torch: indices 216-218 (bright creams/yellows)
|
(local GLOW_CRIMSON pxl8.LIGHT_RED)
|
||||||
(local IDX_TORCH 216)
|
(local GLOW_DEEP_BLUE pxl8.LIGHT_BLUE)
|
||||||
;; Blue/magic: indices 176-178 (purples - brightest of the range)
|
|
||||||
(local IDX_MAGIC 176)
|
|
||||||
|
|
||||||
|
(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 last-gradient-key nil)
|
||||||
(var random-stars [])
|
(var random-stars [])
|
||||||
(var sky-mesh nil)
|
(var sky-mesh nil)
|
||||||
|
|
@ -26,8 +69,8 @@
|
||||||
(var star-directions nil)
|
(var star-directions nil)
|
||||||
(var star-glows nil)
|
(var star-glows nil)
|
||||||
(var star-projected nil)
|
(var star-projected nil)
|
||||||
(var star-time 0)
|
|
||||||
(var tiny-stars [])
|
(var tiny-stars [])
|
||||||
|
(var twinkle-time 0)
|
||||||
|
|
||||||
(fn generate-sky-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b]
|
(fn generate-sky-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b]
|
||||||
(for [i 0 (- SKY_GRADIENT_COUNT 1)]
|
(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)
|
(generate-sky-gradient zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b)
|
||||||
(set last-gradient-key key))))
|
(set last-gradient-key key))))
|
||||||
|
|
||||||
(fn band-factor [dx dy dz bx by bz width]
|
(fn galactic-band-factor [dx dy dz]
|
||||||
(let [dist (math.abs (+ (* dx bx) (* dy by) (* dz bz)))
|
(let [band-len (math.sqrt (+ (* 0.6 0.6) (* 0.3 0.3) (* 0.742 0.742)))
|
||||||
in-band (- 1 (math.min (* dist width) 1))]
|
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)))
|
(* in-band in-band)))
|
||||||
|
|
||||||
(fn galactic-band-factor [dx dy dz]
|
(fn compute-right [cx cy cz]
|
||||||
(let [;; Main galactic band - crosses zenith
|
(if (> (math.abs cy) 0.99)
|
||||||
band-len (math.sqrt (+ (* 0.6 0.6) (* 0.3 0.3) (* 0.742 0.742)))
|
(values 1 0 0)
|
||||||
b1 (band-factor dx dy dz (/ 0.6 band-len) (/ 0.3 band-len) (/ 0.742 band-len) 3)
|
(let [rx (- cz)
|
||||||
;; Secondary band - lower angle, different orientation
|
rz cx
|
||||||
b2 (band-factor dx dy dz 0.8 0.15 0.58 3.5)
|
rlen (math.sqrt (+ (* rx rx) (* rz rz)))]
|
||||||
;; Tertiary band - opposite side
|
(values (/ rx rlen) 0 (/ rz rlen)))))
|
||||||
b3 (band-factor dx dy dz -0.7 0.2 0.69 4)]
|
|
||||||
(math.max b1 b2 b3)))
|
|
||||||
|
|
||||||
(fn generate-stars []
|
(fn generate-constellation-centers []
|
||||||
(set random-stars [])
|
(let [centers []
|
||||||
(set tiny-stars [])
|
seed (+ STAR_SEED 0xC0057E11)
|
||||||
|
num (# CONSTELLATIONS)]
|
||||||
;; Generate random stars - use full upper hemisphere (dy > -0.1)
|
(for [i 0 (- num 1)]
|
||||||
(for [i 0 (- NUM_RANDOM_STARS 1)]
|
(let [h1 (pxl8.hash32 (+ seed (* i 3)))
|
||||||
(let [h1 (pxl8.hash32 (+ STAR_SEED (* i 5)))
|
h2 (pxl8.hash32 (+ seed (* i 3) 1))
|
||||||
h2 (pxl8.hash32 (+ STAR_SEED (* i 5) 1))
|
h1f (/ h1 0xFFFFFFFF)
|
||||||
h3 (pxl8.hash32 (+ STAR_SEED (* i 5) 2))
|
h2f (/ h2 0xFFFFFFFF)
|
||||||
h4 (pxl8.hash32 (+ STAR_SEED (* i 5) 3))
|
base-theta (* (/ i num) TAU)
|
||||||
theta (* (/ h1 0xFFFFFFFF) math.pi 2)
|
theta-jitter (* (- h1f 0.5) 0.3)
|
||||||
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0)))
|
theta-offset (if (= i 0) -0.3 (= i 1) 0.4 (= i 4) 0.5 0)
|
||||||
sin-phi (math.sin phi)
|
theta (+ base-theta theta-jitter theta-offset)
|
||||||
cos-phi (math.cos phi)
|
phi (if (or (= i 0) (= i 6)) (+ 0.25 (* h2f 0.3))
|
||||||
dx (* sin-phi (math.cos theta))
|
(= i 9) (+ 0.5 (* h2f 0.3))
|
||||||
dy cos-phi
|
(or (= i 1) (= i 4) (= i 7) (= i 10)) (+ 0.65 (* h2f 0.4))
|
||||||
dz (* sin-phi (math.sin theta))
|
(= i 3) (+ 1.1 (* h2f 0.2))
|
||||||
brightness-raw (/ (% h3 256) 255)
|
(+ 0.85 (* h2f 0.4)))
|
||||||
brightness (math.floor (+ 60 (* brightness-raw brightness-raw 195)))
|
sin-phi (math.sin phi)
|
||||||
color-type (% h4 100)
|
x (* sin-phi (math.cos theta))
|
||||||
color (if (< color-type 8) (+ IDX_TORCH (% (bit.rshift h4 8) 2))
|
y (math.cos phi)
|
||||||
(< color-type 16) (+ IDX_MAGIC (% (bit.rshift h4 8) 2))
|
z (* sin-phi (math.sin theta))
|
||||||
(+ IDX_SILVER (% (bit.rshift h4 8) 2)))]
|
len (math.sqrt (+ (* x x) (* y y) (* z z)))]
|
||||||
|
(table.insert centers {:x (/ x len) :y (/ y len) :z (/ z len)})))
|
||||||
(when (> dy -0.1)
|
centers))
|
||||||
(table.insert random-stars {:dx dx :dy dy :dz dz
|
|
||||||
:brightness brightness
|
(fn generate-constellation-stars-data []
|
||||||
:color color}))))
|
(let [centers (generate-constellation-centers)
|
||||||
|
stars []]
|
||||||
(let [tiny-seed (+ STAR_SEED 0xCAFEBABE)]
|
(for [i 0 (- (# CONSTELLATIONS) 1)]
|
||||||
(for [i 0 (- NUM_TINY_STARS 1)]
|
(let [constellation (. CONSTELLATIONS (+ i 1))
|
||||||
(let [h1 (pxl8.hash32 (+ tiny-seed (* i 4)))
|
center (. centers (+ i 1))
|
||||||
h2 (pxl8.hash32 (+ tiny-seed (* i 4) 1))
|
(rx ry rz) (compute-right center.x center.y center.z)
|
||||||
h3 (pxl8.hash32 (+ tiny-seed (* i 4) 2))
|
ux (- (* center.y rz) (* center.z ry))
|
||||||
h4 (pxl8.hash32 (+ tiny-seed (* i 4) 3))
|
uy (- (* center.z rx) (* center.x rz))
|
||||||
theta (* (/ h1 0xFFFFFFFF) math.pi 2)
|
uz (- (* center.x ry) (* center.y rx))
|
||||||
phi (math.acos (- 1 (* (/ h2 0xFFFFFFFF) 1.0)))
|
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)
|
sin-phi (math.sin phi)
|
||||||
cos-phi (math.cos phi)
|
|
||||||
dx (* sin-phi (math.cos theta))
|
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))
|
dz (* sin-phi (math.sin theta))
|
||||||
band-boost (galactic-band-factor dx dy dz)
|
band-boost (galactic-band-factor dx dy dz)
|
||||||
base-bright (+ 40 (% h3 50))
|
base-bright (+ 25 (% h3 40))
|
||||||
brightness (+ base-bright (math.floor (* band-boost 40)))
|
brightness (+ base-bright (math.floor (* band-boost 35)))
|
||||||
color-shift (% h4 100)
|
color-shift (% h4 100)
|
||||||
color (if (< color-shift 3) (+ IDX_TORCH (% (bit.rshift h4 8) 2))
|
glow (if (< color-shift 3) GLOW_TORCH
|
||||||
(< color-shift 12) (+ IDX_MAGIC (% (bit.rshift h4 8) 2))
|
(< color-shift 15) GLOW_MAGIC
|
||||||
(+ IDX_SILVER (% (bit.rshift h4 8) 2)))]
|
GLOW_SILVER)]
|
||||||
(when (> dy -0.1)
|
(when (> dy -0.05)
|
||||||
(table.insert tiny-stars {:dx dx :dy dy :dz dz
|
(table.insert stars {:dx dx :dy dy :dz dz
|
||||||
:brightness brightness
|
:brightness brightness :glow glow}))))
|
||||||
:color color})))))
|
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))
|
(set star-directions (pxl8.create_vec3_array star-count))
|
||||||
(when pxl8.create_glows
|
(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 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)
|
(var idx 0)
|
||||||
(each [_ star (ipairs tiny-stars)]
|
(set idx (pack-star-directions tiny-stars idx))
|
||||||
(let [dir (. star-directions idx)]
|
(set idx (pack-star-directions random-stars idx))
|
||||||
(set dir.x star.dx)
|
(set idx (pack-star-directions constellation-stars idx))
|
||||||
(set dir.y star.dy)
|
(set idx (pack-star-directions beacon-stars idx)))
|
||||||
(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))))
|
|
||||||
|
|
||||||
(fn render-stars [cam-x cam-y cam-z intensity dt]
|
(fn star-brightness [time]
|
||||||
(set star-time (+ star-time (or dt 0)))
|
(if (< time 0.18) 1.0
|
||||||
(when (and (> intensity 0) (> star-count 0) star-glows)
|
(< time 0.26) (let [t (/ (- time 0.18) 0.08)
|
||||||
(let [fade-in (* intensity intensity)
|
ease (* t t (- 3.0 (* 2.0 t)))]
|
||||||
time-factor (/ star-time 60)
|
(- 1.0 ease))
|
||||||
star-rotation (/ (* star-time math.pi 2) STAR_CYCLE_PERIOD)
|
(< 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)
|
t (pxl8.mat4_translate cam-x cam-y cam-z)
|
||||||
r (pxl8.mat4_rotate_y star-rotation)
|
r (pxl8.mat4_rotate_y star-rotation)
|
||||||
s (pxl8.mat4_scale sky-radius sky-radius sky-radius)
|
s (pxl8.mat4_scale sky-radius sky-radius sky-radius)
|
||||||
transform (pxl8.mat4_multiply t (pxl8.mat4_multiply r s))
|
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)
|
(star-glows:clear)
|
||||||
(pxl8.project_points star-directions star-projected star-count transform)
|
(pxl8.project_points star-directions star-projected star-count transform)
|
||||||
|
|
||||||
(for [i 0 (- tiny-count 1)]
|
(when (> star-bright 0.02)
|
||||||
(let [screen (. star-projected i)]
|
(for [i 0 (- tiny-count 1)]
|
||||||
(when (> screen.z 0)
|
(let [screen (. star-projected i)]
|
||||||
(let [star (. tiny-stars (+ i 1))
|
(when (> screen.z 0)
|
||||||
int (math.floor (* star.brightness fade-in))]
|
(let [star (. tiny-stars (+ i 1))
|
||||||
(when (> int 8)
|
int (math.floor (* star.brightness fade-in))]
|
||||||
(let [px (math.floor (+ screen.x 0.5))
|
(when (> int 8)
|
||||||
py (math.floor (+ screen.y 0.5))]
|
(star-glows:add (math.floor (+ screen.x 0.5))
|
||||||
(star-glows:add px py 1 int star.color pxl8.GLOW_CIRCLE)))))))
|
(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)
|
(when (> (star-glows:count) 0)
|
||||||
(star-glows:render)))))
|
(star-glows:render)))))
|
||||||
|
|
@ -255,5 +497,9 @@
|
||||||
:generate-stars generate-stars
|
:generate-stars generate-stars
|
||||||
:reset-gradient reset-gradient
|
:reset-gradient reset-gradient
|
||||||
:update-gradient update-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_START SKY_GRADIENT_START
|
||||||
:SKY_GRADIENT_COUNT SKY_GRADIENT_COUNT}
|
:SKY_GRADIENT_COUNT SKY_GRADIENT_COUNT}
|
||||||
|
|
|
||||||
BIN
demo/res/palettes/palette.ase
Normal file
BIN
demo/res/palettes/palette.ase
Normal file
Binary file not shown.
1
pxl8.sh
1
pxl8.sh
|
|
@ -507,6 +507,7 @@ case "$COMMAND" in
|
||||||
src/gfx/pxl8_shader_runtime.c
|
src/gfx/pxl8_shader_runtime.c
|
||||||
src/gfx/pxl8_font.c
|
src/gfx/pxl8_font.c
|
||||||
src/gfx/pxl8_gfx.c
|
src/gfx/pxl8_gfx.c
|
||||||
|
src/gfx/pxl8_glows.c
|
||||||
src/gfx/pxl8_lightmap.c
|
src/gfx/pxl8_lightmap.c
|
||||||
src/gfx/pxl8_lights.c
|
src/gfx/pxl8_lights.c
|
||||||
src/gfx/pxl8_mesh.c
|
src/gfx/pxl8_mesh.c
|
||||||
|
|
|
||||||
|
|
@ -1062,6 +1062,13 @@ pub fn generate_rooms(params: &ProcgenParams) -> Bsp {
|
||||||
})
|
})
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
let mut lights = lights;
|
||||||
|
lights.push(LightSource {
|
||||||
|
position: Vec3::new(860.0, light_height, 416.0),
|
||||||
|
intensity: 1.2,
|
||||||
|
radius: 120.0,
|
||||||
|
});
|
||||||
|
|
||||||
compute_bsp_vertex_lighting(&mut bsp, &lights);
|
compute_bsp_vertex_lighting(&mut bsp, &lights);
|
||||||
|
|
||||||
bsp.into()
|
bsp.into()
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,32 @@ pxl8_bsp_lightmap pxl8_bsp_lightmap_mapped(u8 width, u8 height, u32 offset) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 pxl8_bsp_light_at(const pxl8_bsp* bsp, f32 x, f32 y, f32 z, u8 ambient) {
|
||||||
|
if (!bsp || !bsp->vertices || !bsp->vertex_lights) return 255;
|
||||||
|
|
||||||
|
f32 best_dist = FLT_MAX;
|
||||||
|
u32 best_idx = 0;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < bsp->num_vertices; i++) {
|
||||||
|
f32 dx = bsp->vertices[i].position.x - x;
|
||||||
|
f32 dy = bsp->vertices[i].position.y - y;
|
||||||
|
f32 dz = bsp->vertices[i].position.z - z;
|
||||||
|
f32 dist = dx * dx + dy * dy + dz * dz;
|
||||||
|
if (dist < best_dist) {
|
||||||
|
best_dist = dist;
|
||||||
|
best_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_idx >= bsp->num_vertex_lights) return 255;
|
||||||
|
|
||||||
|
u32 packed = bsp->vertex_lights[best_idx];
|
||||||
|
u8 direct = (packed >> 24) & 0xFF;
|
||||||
|
u8 ao = (packed >> 16) & 0xFF;
|
||||||
|
f32 combined = (f32)direct + ((f32)ambient / 255.0f) * (f32)ao;
|
||||||
|
return (u8)(combined > 255.0f ? 255.0f : combined);
|
||||||
|
}
|
||||||
|
|
||||||
pxl8_bsp_lightmap_sample pxl8_bsp_sample_lightmap(const pxl8_bsp* bsp, u32 face_idx, f32 u, f32 v) {
|
pxl8_bsp_lightmap_sample pxl8_bsp_sample_lightmap(const pxl8_bsp* bsp, u32 face_idx, f32 u, f32 v) {
|
||||||
pxl8_bsp_lightmap_sample white = {255, 255, 255};
|
pxl8_bsp_lightmap_sample white = {255, 255, 255};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ pxl8_bsp_lightmap pxl8_bsp_lightmap_uniform(u8 r, u8 g, u8 b);
|
||||||
pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp);
|
pxl8_result pxl8_bsp_load(const char* path, pxl8_bsp* bsp);
|
||||||
void pxl8_bsp_pvs_destroy(pxl8_bsp_pvs* pvs);
|
void pxl8_bsp_pvs_destroy(pxl8_bsp_pvs* pvs);
|
||||||
bool pxl8_bsp_pvs_is_visible(const pxl8_bsp_pvs* pvs, i32 leaf);
|
bool pxl8_bsp_pvs_is_visible(const pxl8_bsp_pvs* pvs, i32 leaf);
|
||||||
|
u8 pxl8_bsp_light_at(const pxl8_bsp* bsp, f32 x, f32 y, f32 z, u8 ambient);
|
||||||
pxl8_bsp_lightmap_sample pxl8_bsp_sample_lightmap(const pxl8_bsp* bsp, u32 face_idx, f32 u, f32 v);
|
pxl8_bsp_lightmap_sample pxl8_bsp_sample_lightmap(const pxl8_bsp* bsp, u32 face_idx, f32 u, f32 v);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,67 @@ static void generate_blend_table(pxl8_colormap* cm, const u32* palette) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void generate_additive_table(pxl8_colormap* cm, const u32* palette, pxl8_light_color light_color) {
|
||||||
|
pxl8_rgb light = pxl8_light_colors[light_color];
|
||||||
|
u32 base_row = PXL8_ADDITIVE_START + (u32)light_color * PXL8_LIGHT_LEVELS;
|
||||||
|
|
||||||
|
for (u32 level = 0; level < PXL8_LIGHT_LEVELS; level++) {
|
||||||
|
f32 brightness = (f32)level / (f32)(PXL8_LIGHT_LEVELS - 1);
|
||||||
|
u32 row = base_row + level;
|
||||||
|
|
||||||
|
f32 lr = (f32)light.r / 255.0f;
|
||||||
|
f32 lg = (f32)light.g / 255.0f;
|
||||||
|
f32 lb = (f32)light.b / 255.0f;
|
||||||
|
i32 add_r = (i32)(brightness * lr * 255.0f);
|
||||||
|
i32 add_g = (i32)(brightness * lg * 255.0f);
|
||||||
|
i32 add_b = (i32)(brightness * lb * 255.0f);
|
||||||
|
|
||||||
|
for (u32 pal_idx = 0; pal_idx < 256; pal_idx++) {
|
||||||
|
u8 result_idx;
|
||||||
|
|
||||||
|
if (pal_idx == PXL8_TRANSPARENT) {
|
||||||
|
result_idx = PXL8_TRANSPARENT;
|
||||||
|
} else if (pal_idx >= PXL8_FULLBRIGHT_START) {
|
||||||
|
result_idx = (u8)pal_idx;
|
||||||
|
} else {
|
||||||
|
u32 c = palette[pal_idx];
|
||||||
|
i32 r = (i32)(c & 0xFF);
|
||||||
|
i32 g = (i32)((c >> 8) & 0xFF);
|
||||||
|
i32 b = (i32)((c >> 16) & 0xFF);
|
||||||
|
|
||||||
|
i32 tr = r + add_r;
|
||||||
|
i32 tg = g + add_g;
|
||||||
|
i32 tb = b + add_b;
|
||||||
|
|
||||||
|
result_idx = find_closest_color(palette,
|
||||||
|
(u8)(tr > 255 ? 255 : tr),
|
||||||
|
(u8)(tg > 255 ? 255 : tg),
|
||||||
|
(u8)(tb > 255 ? 255 : tb));
|
||||||
|
}
|
||||||
|
|
||||||
|
cm->table[row * 256 + pal_idx] = result_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generate_luminance_table(pxl8_colormap* cm, const u32* palette) {
|
||||||
|
for (u32 i = 0; i < 256; i++) {
|
||||||
|
u32 c = palette[i];
|
||||||
|
u32 r = c & 0xFF;
|
||||||
|
u32 g = (c >> 8) & 0xFF;
|
||||||
|
u32 b = (c >> 16) & 0xFF;
|
||||||
|
cm->luminance[i] = (u8)((77 * r + 150 * g + 29 * b) >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette) {
|
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette) {
|
||||||
if (!cm || !palette) return;
|
if (!cm || !palette) return;
|
||||||
|
|
||||||
for (u32 light = 0; light < PXL8_LIGHT_COLORS; light++) {
|
for (u32 light = 0; light < PXL8_LIGHT_COLORS; light++) {
|
||||||
generate_light_table(cm, palette, (pxl8_light_color)light);
|
generate_light_table(cm, palette, (pxl8_light_color)light);
|
||||||
|
generate_additive_table(cm, palette, (pxl8_light_color)light);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_blend_table(cm, palette);
|
generate_blend_table(cm, palette);
|
||||||
|
generate_luminance_table(cm, palette);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ extern "C" {
|
||||||
#define PXL8_LIGHT_LEVELS 8
|
#define PXL8_LIGHT_LEVELS 8
|
||||||
#define PXL8_LIGHT_ROWS (PXL8_LIGHT_COLORS * PXL8_LIGHT_LEVELS)
|
#define PXL8_LIGHT_ROWS (PXL8_LIGHT_COLORS * PXL8_LIGHT_LEVELS)
|
||||||
#define PXL8_BLEND_ROWS 256
|
#define PXL8_BLEND_ROWS 256
|
||||||
#define PXL8_COLORMAP_ROWS (PXL8_LIGHT_ROWS + PXL8_BLEND_ROWS)
|
#define PXL8_ADDITIVE_ROWS (PXL8_LIGHT_COLORS * PXL8_LIGHT_LEVELS)
|
||||||
|
#define PXL8_ADDITIVE_START (PXL8_LIGHT_ROWS + PXL8_BLEND_ROWS)
|
||||||
|
#define PXL8_COLORMAP_ROWS (PXL8_LIGHT_ROWS + PXL8_BLEND_ROWS + PXL8_ADDITIVE_ROWS)
|
||||||
#define PXL8_COLORMAP_SIZE (256 * PXL8_COLORMAP_ROWS)
|
#define PXL8_COLORMAP_SIZE (256 * PXL8_COLORMAP_ROWS)
|
||||||
|
|
||||||
#define PXL8_FULLBRIGHT_START 240
|
#define PXL8_FULLBRIGHT_START 240
|
||||||
|
|
@ -47,6 +49,7 @@ static const pxl8_rgb pxl8_light_colors[PXL8_LIGHT_COLORS] = {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 table[PXL8_COLORMAP_SIZE];
|
u8 table[PXL8_COLORMAP_SIZE];
|
||||||
|
u8 luminance[256];
|
||||||
} pxl8_colormap;
|
} pxl8_colormap;
|
||||||
|
|
||||||
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette);
|
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette);
|
||||||
|
|
@ -68,6 +71,17 @@ static inline u8 pxl8_colormap_blend(const pxl8_colormap* cm, u8 src, u8 dst) {
|
||||||
return cm->table[(blend_row << 8) + dst];
|
return cm->table[(blend_row << 8) + dst];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u8 pxl8_colormap_additive(const pxl8_colormap* cm, u8 pal_idx, pxl8_light_color light_color, u8 intensity) {
|
||||||
|
u32 row = PXL8_ADDITIVE_START + ((u32)light_color << 3) + (intensity >> 5);
|
||||||
|
return cm->table[(row << 8) + pal_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 pxl8_colormap_additive_dithered(const pxl8_colormap* cm, u8 pal_idx, pxl8_light_color light_color, u8 intensity, u32 x, u32 y) {
|
||||||
|
u8 dithered = pxl8_gfx_dither((f32)intensity + 0.5f, x, y);
|
||||||
|
u32 row = PXL8_ADDITIVE_START + ((u32)light_color << 3) + (dithered >> 5);
|
||||||
|
return cm->table[(row << 8) + pal_idx];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "pxl8_color.h"
|
#include "pxl8_color.h"
|
||||||
#include "pxl8_colormap.h"
|
#include "pxl8_colormap.h"
|
||||||
#include "pxl8_font.h"
|
#include "pxl8_font.h"
|
||||||
|
#include "pxl8_glows.h"
|
||||||
#include "pxl8_hal.h"
|
#include "pxl8_hal.h"
|
||||||
#include "pxl8_log.h"
|
#include "pxl8_log.h"
|
||||||
#include "pxl8_macros.h"
|
#include "pxl8_macros.h"
|
||||||
|
|
@ -694,6 +695,7 @@ void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8
|
||||||
|
|
||||||
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
|
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
|
||||||
frame.bsp = gfx->bsp;
|
frame.bsp = gfx->bsp;
|
||||||
|
frame.uniforms.camera_pos = frame.camera_pos;
|
||||||
frame.uniforms.lights = lights ? pxl8_lights_data(lights) : NULL;
|
frame.uniforms.lights = lights ? pxl8_lights_data(lights) : NULL;
|
||||||
frame.uniforms.lights_count = lights ? pxl8_lights_count(lights) : 0;
|
frame.uniforms.lights_count = lights ? pxl8_lights_count(lights) : 0;
|
||||||
|
|
||||||
|
|
@ -765,7 +767,7 @@ void pxl8_3d_clear(pxl8_gfx* gfx, u8 color) {
|
||||||
|
|
||||||
void pxl8_3d_clear_depth(pxl8_gfx* gfx) {
|
void pxl8_3d_clear_depth(pxl8_gfx* gfx) {
|
||||||
if (!gfx) return;
|
if (!gfx) return;
|
||||||
pxl8_clear_depth(gfx->renderer, gfx_current_depth(gfx));
|
pxl8_cmdbuf_clear_depth(gfx->cmdbuf, gfx_current_depth(gfx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color) {
|
void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color) {
|
||||||
|
|
@ -1043,6 +1045,107 @@ bool pxl8_gfx_get_wireframe(const pxl8_gfx* gfx) {
|
||||||
return gfx ? gfx->wireframe : false;
|
return gfx ? gfx->wireframe : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count) {
|
||||||
|
if (!gfx || !params || count == 0) return;
|
||||||
|
|
||||||
|
if (effect == PXL8_GFX_EFFECT_GLOWS) {
|
||||||
|
u8* fb = (u8*)pxl8_texture_get_data(gfx->renderer, gfx_current_color(gfx));
|
||||||
|
if (!fb || !gfx->colormap) return;
|
||||||
|
|
||||||
|
u16* zb = (u16*)pxl8_texture_get_data(gfx->renderer, gfx_current_depth(gfx));
|
||||||
|
i32 w = gfx->framebuffer_width;
|
||||||
|
i32 h = gfx->framebuffer_height;
|
||||||
|
const pxl8_glow* glows = (const pxl8_glow*)params;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count; i++) {
|
||||||
|
const pxl8_glow* g = &glows[i];
|
||||||
|
i32 cx = g->x;
|
||||||
|
i32 cy = g->y;
|
||||||
|
i32 r = (i32)g->radius;
|
||||||
|
if (r <= 0) continue;
|
||||||
|
|
||||||
|
bool depth_test = g->depth > 0 && zb;
|
||||||
|
f32 base_intensity = (f32)g->intensity / 255.0f;
|
||||||
|
f32 inv_r = 1.0f / (f32)r;
|
||||||
|
|
||||||
|
i32 x0 = cx - r;
|
||||||
|
i32 y0 = cy - r;
|
||||||
|
i32 x1 = cx + r;
|
||||||
|
i32 y1 = cy + r;
|
||||||
|
|
||||||
|
if (g->shape == PXL8_GLOW_SHAFT) {
|
||||||
|
i32 sh = (i32)g->height;
|
||||||
|
if (sh <= 0) sh = 1;
|
||||||
|
y0 = cy - sh;
|
||||||
|
y1 = cy + sh;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x0 < 0) x0 = 0;
|
||||||
|
if (y0 < 0) y0 = 0;
|
||||||
|
if (x1 >= w) x1 = w - 1;
|
||||||
|
if (y1 >= h) y1 = h - 1;
|
||||||
|
|
||||||
|
for (i32 py = y0; py <= y1; py++) {
|
||||||
|
i32 dy = py - cy;
|
||||||
|
for (i32 px = x0; px <= x1; px++) {
|
||||||
|
i32 idx = py * w + px;
|
||||||
|
|
||||||
|
if (depth_test && zb[idx] < g->depth) continue;
|
||||||
|
|
||||||
|
u8 src = fb[idx];
|
||||||
|
if (src == PXL8_TRANSPARENT) continue;
|
||||||
|
|
||||||
|
i32 dx = px - cx;
|
||||||
|
f32 falloff;
|
||||||
|
|
||||||
|
switch (g->shape) {
|
||||||
|
case PXL8_GLOW_CIRCLE: {
|
||||||
|
f32 dist_sq = (f32)(dx * dx + dy * dy);
|
||||||
|
f32 norm = dist_sq * inv_r * inv_r;
|
||||||
|
if (norm >= 1.0f) continue;
|
||||||
|
falloff = 1.0f - norm;
|
||||||
|
falloff *= falloff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PXL8_GLOW_DIAMOND: {
|
||||||
|
f32 manhattan = (f32)(abs(dx) + abs(dy));
|
||||||
|
f32 norm = manhattan * inv_r;
|
||||||
|
if (norm >= 1.0f) continue;
|
||||||
|
falloff = 1.0f - norm;
|
||||||
|
falloff *= falloff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PXL8_GLOW_SHAFT: {
|
||||||
|
f32 abs_dx = (f32)abs(dx);
|
||||||
|
if (abs_dx >= (f32)r) continue;
|
||||||
|
f32 x_falloff = 1.0f - abs_dx * inv_r;
|
||||||
|
i32 sh = (i32)g->height;
|
||||||
|
if (sh <= 0) sh = 1;
|
||||||
|
f32 abs_dy = (f32)abs(dy);
|
||||||
|
f32 y_falloff = 1.0f - abs_dy / (f32)sh;
|
||||||
|
falloff = x_falloff * y_falloff;
|
||||||
|
falloff *= falloff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 brightness = falloff * base_intensity;
|
||||||
|
f32 raw = brightness * 255.0f;
|
||||||
|
if (raw > 255.0f) raw = 255.0f;
|
||||||
|
u8 light_u8 = (u8)raw;
|
||||||
|
if (light_u8 < 4) continue;
|
||||||
|
|
||||||
|
fb[idx] = pxl8_colormap_additive_dithered(
|
||||||
|
gfx->colormap, src, g->color,
|
||||||
|
light_u8, (u32)px, (u32)py
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8 pxl8_gfx_get_ambient(const pxl8_gfx* gfx) {
|
u8 pxl8_gfx_get_ambient(const pxl8_gfx* gfx) {
|
||||||
return gfx ? gfx->frame.uniforms.ambient : 0;
|
return gfx ? gfx->frame.uniforms.ambient : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ void pxl8_glows_destroy(pxl8_glows* glows) {
|
||||||
pxl8_free(glows);
|
pxl8_free(glows);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) {
|
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape, u16 depth) {
|
||||||
if (!glows || glows->count >= glows->capacity) return;
|
if (!glows || glows->count >= glows->capacity) return;
|
||||||
|
|
||||||
pxl8_glow* g = &glows->data[glows->count++];
|
pxl8_glow* g = &glows->data[glows->count++];
|
||||||
|
|
@ -43,7 +43,7 @@ void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u
|
||||||
g->intensity = intensity;
|
g->intensity = intensity;
|
||||||
g->color = color;
|
g->color = color;
|
||||||
g->shape = shape;
|
g->shape = shape;
|
||||||
g->depth = 0xFFFF;
|
g->depth = depth;
|
||||||
g->height = 0;
|
g->height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ extern "C" {
|
||||||
pxl8_glows* pxl8_glows_create(u32 capacity);
|
pxl8_glows* pxl8_glows_create(u32 capacity);
|
||||||
void pxl8_glows_destroy(pxl8_glows* glows);
|
void pxl8_glows_destroy(pxl8_glows* glows);
|
||||||
|
|
||||||
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape);
|
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape, u16 depth);
|
||||||
void pxl8_glows_clear(pxl8_glows* glows);
|
void pxl8_glows_clear(pxl8_glows* glows);
|
||||||
u32 pxl8_glows_count(const pxl8_glows* glows);
|
u32 pxl8_glows_count(const pxl8_glows* glows);
|
||||||
const pxl8_glow* pxl8_glows_data(const pxl8_glows* glows);
|
const pxl8_glow* pxl8_glows_data(const pxl8_glows* glows);
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ static void pxl8_palette_sort_colors(pxl8_palette* pal) {
|
||||||
|
|
||||||
pal->color_ramp[0] = 0;
|
pal->color_ramp[0] = 0;
|
||||||
|
|
||||||
u8 count = pal->color_count;
|
u16 count = pal->color_count;
|
||||||
palette_sort_entry entries[PXL8_PALETTE_SIZE - 1];
|
palette_sort_entry entries[PXL8_PALETTE_SIZE - 1];
|
||||||
for (u32 i = 1; i < count; i++) {
|
for (u32 i = 1; i < count; i++) {
|
||||||
u8 r, g, b, a;
|
u8 r, g, b, a;
|
||||||
|
|
|
||||||
|
|
@ -87,18 +87,15 @@ static u8 blend_indexed(
|
||||||
const pxl8_gfx_pipeline_desc* pipeline,
|
const pxl8_gfx_pipeline_desc* pipeline,
|
||||||
u8 src,
|
u8 src,
|
||||||
u8 dst,
|
u8 dst,
|
||||||
const u32* palette,
|
const u32* palette
|
||||||
const u8* colormap
|
|
||||||
) {
|
) {
|
||||||
(void)colormap;
|
|
||||||
if (!pipeline || !pipeline->blend.enabled) return src;
|
if (!pipeline || !pipeline->blend.enabled) return src;
|
||||||
if (src == 0) return dst;
|
if (src == 0) return dst;
|
||||||
if (!palette) return src;
|
if (!palette) return src;
|
||||||
|
|
||||||
f32 src_a = src == 0 ? 0.0f : 1.0f;
|
|
||||||
f32 dst_a = dst == 0 ? 0.0f : 1.0f;
|
f32 dst_a = dst == 0 ? 0.0f : 1.0f;
|
||||||
f32 sf = blend_factor_value(pipeline->blend.src, src_a, dst_a);
|
f32 sf = blend_factor_value(pipeline->blend.src, 1.0f, dst_a);
|
||||||
f32 df = blend_factor_value(pipeline->blend.dst, src_a, dst_a);
|
f32 df = blend_factor_value(pipeline->blend.dst, 1.0f, dst_a);
|
||||||
|
|
||||||
if (sf == 1.0f && df == 0.0f) return src;
|
if (sf == 1.0f && df == 0.0f) return src;
|
||||||
if (sf == 0.0f && df == 1.0f) return dst;
|
if (sf == 0.0f && df == 1.0f) return dst;
|
||||||
|
|
@ -111,18 +108,11 @@ static u8 blend_indexed(
|
||||||
u8 dg = (palette[dst] >> 8) & 0xFF;
|
u8 dg = (palette[dst] >> 8) & 0xFF;
|
||||||
u8 db = (palette[dst] >> 16) & 0xFF;
|
u8 db = (palette[dst] >> 16) & 0xFF;
|
||||||
|
|
||||||
i32 out_r = (i32)(sr * sf + dr * df);
|
u8 out_r = (u8)pxl8_clamp_byte((i32)(sr * sf + dr * df));
|
||||||
i32 out_g = (i32)(sg * sf + dg * df);
|
u8 out_g = (u8)pxl8_clamp_byte((i32)(sg * sf + dg * df));
|
||||||
i32 out_b = (i32)(sb * sf + db * df);
|
u8 out_b = (u8)pxl8_clamp_byte((i32)(sb * sf + db * df));
|
||||||
|
|
||||||
if (out_r < 0) out_r = 0;
|
return palette_find_closest(palette, out_r, out_g, out_b);
|
||||||
if (out_g < 0) out_g = 0;
|
|
||||||
if (out_b < 0) out_b = 0;
|
|
||||||
if (out_r > 255) out_r = 255;
|
|
||||||
if (out_g > 255) out_g = 255;
|
|
||||||
if (out_b > 255) out_b = 255;
|
|
||||||
|
|
||||||
return palette_find_closest(palette, (u8)out_r, (u8)out_g, (u8)out_b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pxl8_vec4 vec4_lerp(pxl8_vec4 a, pxl8_vec4 b, f32 t) {
|
static inline pxl8_vec4 vec4_lerp(pxl8_vec4 a, pxl8_vec4 b, f32 t) {
|
||||||
|
|
@ -192,6 +182,15 @@ static i32 clip_triangle_near(
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline pxl8_vec3 clip_to_screen(pxl8_vec4 clip, f32 vp_x, f32 vp_y, f32 hw, f32 hh) {
|
||||||
|
f32 inv_w = 1.0f / clip.w;
|
||||||
|
return (pxl8_vec3){
|
||||||
|
vp_x + hw + clip.x * inv_w * hw,
|
||||||
|
vp_y + hh - clip.y * inv_w * hh,
|
||||||
|
clip.z * inv_w,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static bool setup_tri(
|
static bool setup_tri(
|
||||||
tri_setup* setup,
|
tri_setup* setup,
|
||||||
const raster_vertex* vo0, const raster_vertex* vo1, const raster_vertex* vo2,
|
const raster_vertex* vo0, const raster_vertex* vo1, const raster_vertex* vo2,
|
||||||
|
|
@ -203,18 +202,12 @@ static bool setup_tri(
|
||||||
|
|
||||||
f32 hw = (f32)viewport_w * 0.5f;
|
f32 hw = (f32)viewport_w * 0.5f;
|
||||||
f32 hh = (f32)viewport_h * 0.5f;
|
f32 hh = (f32)viewport_h * 0.5f;
|
||||||
|
f32 vp_xf = (f32)viewport_x;
|
||||||
|
f32 vp_yf = (f32)viewport_y;
|
||||||
|
|
||||||
setup->p0.x = (f32)viewport_x + hw + vo0->clip_pos.x / vo0->clip_pos.w * hw;
|
setup->p0 = clip_to_screen(vo0->clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
setup->p0.y = (f32)viewport_y + hh - vo0->clip_pos.y / vo0->clip_pos.w * hh;
|
setup->p1 = clip_to_screen(vo1->clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
setup->p0.z = vo0->clip_pos.z / vo0->clip_pos.w;
|
setup->p2 = clip_to_screen(vo2->clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
|
|
||||||
setup->p1.x = (f32)viewport_x + hw + vo1->clip_pos.x / vo1->clip_pos.w * hw;
|
|
||||||
setup->p1.y = (f32)viewport_y + hh - vo1->clip_pos.y / vo1->clip_pos.w * hh;
|
|
||||||
setup->p1.z = vo1->clip_pos.z / vo1->clip_pos.w;
|
|
||||||
|
|
||||||
setup->p2.x = (f32)viewport_x + hw + vo2->clip_pos.x / vo2->clip_pos.w * hw;
|
|
||||||
setup->p2.y = (f32)viewport_y + hh - vo2->clip_pos.y / vo2->clip_pos.w * hh;
|
|
||||||
setup->p2.z = vo2->clip_pos.z / vo2->clip_pos.w;
|
|
||||||
|
|
||||||
f32 cross = (setup->p1.x - setup->p0.x) * (setup->p2.y - setup->p0.y) -
|
f32 cross = (setup->p1.x - setup->p0.x) * (setup->p2.y - setup->p0.y) -
|
||||||
(setup->p1.y - setup->p0.y) * (setup->p2.x - setup->p0.x);
|
(setup->p1.y - setup->p0.y) * (setup->p2.x - setup->p0.x);
|
||||||
|
|
@ -303,7 +296,6 @@ static void rasterize_triangle(
|
||||||
u8 alpha_ref = pipeline ? pipeline->blend.alpha_ref : 0;
|
u8 alpha_ref = pipeline ? pipeline->blend.alpha_ref : 0;
|
||||||
bool blend_enabled = pipeline && pipeline->blend.enabled;
|
bool blend_enabled = pipeline && pipeline->blend.enabled;
|
||||||
const u32* palette = bindings ? bindings->palette : NULL;
|
const u32* palette = bindings ? bindings->palette : NULL;
|
||||||
const u8* colormap = bindings ? bindings->colormap : NULL;
|
|
||||||
|
|
||||||
for (i32 y = setup->y_start; y <= setup->y_end; y++) {
|
for (i32 y = setup->y_start; y <= setup->y_end; y++) {
|
||||||
f32 yf = (f32)y + 0.5f;
|
f32 yf = (f32)y + 0.5f;
|
||||||
|
|
@ -548,7 +540,7 @@ static void rasterize_triangle(
|
||||||
if (color != 0) {
|
if (color != 0) {
|
||||||
u8 out_color = color;
|
u8 out_color = color;
|
||||||
if (blend_enabled) {
|
if (blend_enabled) {
|
||||||
out_color = blend_indexed(pipeline, color, prow[px], palette, colormap);
|
out_color = blend_indexed(pipeline, color, prow[px], palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
prow[px] = out_color;
|
prow[px] = out_color;
|
||||||
|
|
@ -594,7 +586,7 @@ static void rasterize_triangle(
|
||||||
if (color != 0) {
|
if (color != 0) {
|
||||||
u8 out_color = color;
|
u8 out_color = color;
|
||||||
if (blend_enabled) {
|
if (blend_enabled) {
|
||||||
out_color = blend_indexed(pipeline, color, prow[px], palette, colormap);
|
out_color = blend_indexed(pipeline, color, prow[px], palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
prow[px] = out_color;
|
prow[px] = out_color;
|
||||||
|
|
@ -1142,6 +1134,12 @@ void pxl8_begin_pass(pxl8_gfx_cmdbuf* cb, pxl8_gfx_pass pass) {
|
||||||
cmd->begin_pass.pass = pass;
|
cmd->begin_pass.pass = pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pxl8_cmdbuf_clear_depth(pxl8_gfx_cmdbuf* cb, pxl8_gfx_texture texture) {
|
||||||
|
pxl8_gfx_cmd* cmd = cmd_alloc(cb);
|
||||||
|
cmd->type = PXL8_GFX_CMD_CLEAR_DEPTH;
|
||||||
|
cmd->clear_depth.texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
void pxl8_end_pass(pxl8_gfx_cmdbuf* cb) {
|
void pxl8_end_pass(pxl8_gfx_cmdbuf* cb) {
|
||||||
pxl8_gfx_cmd* cmd = cmd_alloc(cb);
|
pxl8_gfx_cmd* cmd = cmd_alloc(cb);
|
||||||
cmd->type = PXL8_GFX_CMD_END_PASS;
|
cmd->type = PXL8_GFX_CMD_END_PASS;
|
||||||
|
|
@ -1370,17 +1368,16 @@ static void execute_draw(
|
||||||
if (is_wireframe) {
|
if (is_wireframe) {
|
||||||
f32 hw = (f32)vp_w * 0.5f;
|
f32 hw = (f32)vp_w * 0.5f;
|
||||||
f32 hh = (f32)vp_h * 0.5f;
|
f32 hh = (f32)vp_h * 0.5f;
|
||||||
|
f32 vp_xf = (f32)vp_x;
|
||||||
|
f32 vp_yf = (f32)vp_y;
|
||||||
|
|
||||||
raster_vertex* wv0 = &clipped[t];
|
pxl8_vec3 s0 = clip_to_screen(clipped[t].clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
raster_vertex* wv1 = &clipped[t+1];
|
pxl8_vec3 s1 = clip_to_screen(clipped[t+1].clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
raster_vertex* wv2 = &clipped[t+2];
|
pxl8_vec3 s2 = clip_to_screen(clipped[t+2].clip_pos, vp_xf, vp_yf, hw, hh);
|
||||||
|
|
||||||
i32 sx0 = (i32)((f32)vp_x + hw + wv0->clip_pos.x / wv0->clip_pos.w * hw);
|
i32 sx0 = (i32)s0.x, sy0 = (i32)s0.y;
|
||||||
i32 sy0 = (i32)((f32)vp_y + hh - wv0->clip_pos.y / wv0->clip_pos.w * hh);
|
i32 sx1 = (i32)s1.x, sy1 = (i32)s1.y;
|
||||||
i32 sx1 = (i32)((f32)vp_x + hw + wv1->clip_pos.x / wv1->clip_pos.w * hw);
|
i32 sx2 = (i32)s2.x, sy2 = (i32)s2.y;
|
||||||
i32 sy1 = (i32)((f32)vp_y + hh - wv1->clip_pos.y / wv1->clip_pos.w * hh);
|
|
||||||
i32 sx2 = (i32)((f32)vp_x + hw + wv2->clip_pos.x / wv2->clip_pos.w * hw);
|
|
||||||
i32 sy2 = (i32)((f32)vp_y + hh - wv2->clip_pos.y / wv2->clip_pos.w * hh);
|
|
||||||
|
|
||||||
f32 cross = (f32)(sx1 - sx0) * (f32)(sy2 - sy0) - (f32)(sy1 - sy0) * (f32)(sx2 - sx0);
|
f32 cross = (f32)(sx1 - sx0) * (f32)(sy2 - sy0) - (f32)(sy1 - sy0) * (f32)(sx2 - sx0);
|
||||||
if (!double_sided) {
|
if (!double_sided) {
|
||||||
|
|
@ -1427,6 +1424,9 @@ void pxl8_gfx_submit(pxl8_renderer* r, pxl8_gfx_cmdbuf* cb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PXL8_GFX_CMD_CLEAR_DEPTH:
|
||||||
|
pxl8_clear_depth(r, cmd->clear_depth.texture);
|
||||||
|
break;
|
||||||
case PXL8_GFX_CMD_END_PASS:
|
case PXL8_GFX_CMD_END_PASS:
|
||||||
r->current_pass = (pxl8_gfx_pass){ PXL8_GFX_INVALID_ID };
|
r->current_pass = (pxl8_gfx_pass){ PXL8_GFX_INVALID_ID };
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ void pxl8_cmdbuf_destroy(pxl8_gfx_cmdbuf* cb);
|
||||||
void pxl8_cmdbuf_reset(pxl8_gfx_cmdbuf* cb);
|
void pxl8_cmdbuf_reset(pxl8_gfx_cmdbuf* cb);
|
||||||
|
|
||||||
void pxl8_begin_pass(pxl8_gfx_cmdbuf* cb, pxl8_gfx_pass pass);
|
void pxl8_begin_pass(pxl8_gfx_cmdbuf* cb, pxl8_gfx_pass pass);
|
||||||
|
void pxl8_cmdbuf_clear_depth(pxl8_gfx_cmdbuf* cb, pxl8_gfx_texture texture);
|
||||||
void pxl8_end_pass(pxl8_gfx_cmdbuf* cb);
|
void pxl8_end_pass(pxl8_gfx_cmdbuf* cb);
|
||||||
void pxl8_set_bindings(pxl8_gfx_cmdbuf* cb, pxl8_gfx_bindings bindings);
|
void pxl8_set_bindings(pxl8_gfx_cmdbuf* cb, pxl8_gfx_bindings bindings);
|
||||||
void pxl8_set_draw_params(pxl8_gfx_cmdbuf* cb, const pxl8_gfx_cmd_draw_params* p);
|
void pxl8_set_draw_params(pxl8_gfx_cmdbuf* cb, const pxl8_gfx_cmd_draw_params* p);
|
||||||
|
|
|
||||||
|
|
@ -177,14 +177,15 @@ typedef struct pxl8_gfx_cmd_draw_params {
|
||||||
|
|
||||||
typedef enum pxl8_gfx_cmd_type {
|
typedef enum pxl8_gfx_cmd_type {
|
||||||
PXL8_GFX_CMD_BEGIN_PASS,
|
PXL8_GFX_CMD_BEGIN_PASS,
|
||||||
PXL8_GFX_CMD_END_PASS,
|
PXL8_GFX_CMD_CLEAR_DEPTH,
|
||||||
PXL8_GFX_CMD_SET_PIPELINE,
|
|
||||||
PXL8_GFX_CMD_SET_BINDINGS,
|
|
||||||
PXL8_GFX_CMD_SET_VIEWPORT,
|
|
||||||
PXL8_GFX_CMD_SET_SCISSOR,
|
|
||||||
PXL8_GFX_CMD_SET_DRAW_PARAMS,
|
|
||||||
PXL8_GFX_CMD_DRAW,
|
PXL8_GFX_CMD_DRAW,
|
||||||
|
PXL8_GFX_CMD_END_PASS,
|
||||||
PXL8_GFX_CMD_RESOLVE,
|
PXL8_GFX_CMD_RESOLVE,
|
||||||
|
PXL8_GFX_CMD_SET_BINDINGS,
|
||||||
|
PXL8_GFX_CMD_SET_DRAW_PARAMS,
|
||||||
|
PXL8_GFX_CMD_SET_PIPELINE,
|
||||||
|
PXL8_GFX_CMD_SET_SCISSOR,
|
||||||
|
PXL8_GFX_CMD_SET_VIEWPORT,
|
||||||
} pxl8_gfx_cmd_type;
|
} pxl8_gfx_cmd_type;
|
||||||
|
|
||||||
typedef struct pxl8_gfx_cmd_begin_pass {
|
typedef struct pxl8_gfx_cmd_begin_pass {
|
||||||
|
|
@ -217,6 +218,10 @@ typedef struct pxl8_gfx_cmd_draw {
|
||||||
u32 index_count;
|
u32 index_count;
|
||||||
} pxl8_gfx_cmd_draw;
|
} pxl8_gfx_cmd_draw;
|
||||||
|
|
||||||
|
typedef struct pxl8_gfx_cmd_clear_depth {
|
||||||
|
pxl8_gfx_texture texture;
|
||||||
|
} pxl8_gfx_cmd_clear_depth;
|
||||||
|
|
||||||
typedef struct pxl8_gfx_cmd_resolve {
|
typedef struct pxl8_gfx_cmd_resolve {
|
||||||
pxl8_gfx_texture src;
|
pxl8_gfx_texture src;
|
||||||
u32* output;
|
u32* output;
|
||||||
|
|
@ -226,13 +231,14 @@ typedef struct pxl8_gfx_cmd {
|
||||||
pxl8_gfx_cmd_type type;
|
pxl8_gfx_cmd_type type;
|
||||||
union {
|
union {
|
||||||
pxl8_gfx_cmd_begin_pass begin_pass;
|
pxl8_gfx_cmd_begin_pass begin_pass;
|
||||||
pxl8_gfx_cmd_set_pipeline set_pipeline;
|
pxl8_gfx_cmd_clear_depth clear_depth;
|
||||||
pxl8_gfx_cmd_set_bindings set_bindings;
|
|
||||||
pxl8_gfx_cmd_set_viewport set_viewport;
|
|
||||||
pxl8_gfx_cmd_set_scissor set_scissor;
|
|
||||||
pxl8_gfx_cmd_draw draw;
|
pxl8_gfx_cmd_draw draw;
|
||||||
pxl8_gfx_cmd_draw_params draw_params;
|
pxl8_gfx_cmd_draw_params draw_params;
|
||||||
pxl8_gfx_cmd_resolve resolve;
|
pxl8_gfx_cmd_resolve resolve;
|
||||||
|
pxl8_gfx_cmd_set_bindings set_bindings;
|
||||||
|
pxl8_gfx_cmd_set_pipeline set_pipeline;
|
||||||
|
pxl8_gfx_cmd_set_scissor set_scissor;
|
||||||
|
pxl8_gfx_cmd_set_viewport set_viewport;
|
||||||
};
|
};
|
||||||
} pxl8_gfx_cmd;
|
} pxl8_gfx_cmd;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ typedef struct pxl8_vertex_out {
|
||||||
typedef struct pxl8_shader_uniforms {
|
typedef struct pxl8_shader_uniforms {
|
||||||
u8 ambient;
|
u8 ambient;
|
||||||
bool baked_lighting;
|
bool baked_lighting;
|
||||||
|
pxl8_vec3 camera_pos;
|
||||||
pxl8_vec3 celestial_dir;
|
pxl8_vec3 celestial_dir;
|
||||||
f32 celestial_intensity;
|
f32 celestial_intensity;
|
||||||
bool dither;
|
bool dither;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ void pxl8_shader_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_f32_simd light = ctx->v_light;
|
pxl8_f32_simd light = ctx->v_light;
|
||||||
|
pxl8_f32_simd dynamic_total = pxl8_f32_simd_zero();
|
||||||
f32 max_strength[4] = {0, 0, 0, 0};
|
f32 max_strength[4] = {0, 0, 0, 0};
|
||||||
u8 dominant_color[4] = {0, 0, 0, 0};
|
u8 dominant_color[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
|
@ -101,10 +102,31 @@ void pxl8_shader_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
light = pxl8_f32_simd_add(light, strength);
|
light = pxl8_f32_simd_add(light, strength);
|
||||||
|
dynamic_total = pxl8_f32_simd_add(dynamic_total, strength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
light = pxl8_f32_simd_clamp(light, pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f));
|
light = pxl8_f32_simd_clamp(light, pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f));
|
||||||
|
dynamic_total = pxl8_f32_simd_clamp(dynamic_total, pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f));
|
||||||
|
|
||||||
|
if (uniforms && uniforms->fog_density > 0.0f) {
|
||||||
|
pxl8_vec3_simd cam = pxl8_vec3_simd_set(uniforms->camera_pos);
|
||||||
|
pxl8_vec3_simd to_frag = pxl8_vec3_simd_sub(ctx->v_world, cam);
|
||||||
|
pxl8_f32_simd dist_sq = pxl8_vec3_simd_dot(to_frag, to_frag);
|
||||||
|
pxl8_f32_simd fog_sq = pxl8_f32_simd_set(uniforms->fog_density * uniforms->fog_density);
|
||||||
|
pxl8_f32_simd fog = pxl8_f32_simd_clamp(
|
||||||
|
pxl8_f32_simd_mul(dist_sq, fog_sq),
|
||||||
|
pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f)
|
||||||
|
);
|
||||||
|
light = pxl8_f32_simd_mul(light, pxl8_f32_simd_sub(pxl8_f32_simd_set(1.0f), fog));
|
||||||
|
pxl8_f32_simd scatter = pxl8_f32_simd_mul(
|
||||||
|
pxl8_f32_simd_mul(dynamic_total, fog),
|
||||||
|
pxl8_f32_simd_set(0.4f)
|
||||||
|
);
|
||||||
|
light = pxl8_f32_simd_add(light, scatter);
|
||||||
|
light = pxl8_f32_simd_clamp(light, pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
pxl8_f32_simd light_f = pxl8_f32_simd_mul(light, pxl8_f32_simd_set(255.0f));
|
pxl8_f32_simd light_f = pxl8_f32_simd_mul(light, pxl8_f32_simd_set(255.0f));
|
||||||
|
|
||||||
f32 light_arr[4];
|
f32 light_arr[4];
|
||||||
|
|
@ -133,6 +155,7 @@ void pxl8_shader_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 light = ctx->v_light;
|
f32 light = ctx->v_light;
|
||||||
|
f32 dynamic_total = 0.0f;
|
||||||
f32 max_strength = 0;
|
f32 max_strength = 0;
|
||||||
u8 dominant_color = 0;
|
u8 dominant_color = 0;
|
||||||
|
|
||||||
|
|
@ -178,11 +201,25 @@ void pxl8_shader_lit(
|
||||||
dominant_color = l->color;
|
dominant_color = l->color;
|
||||||
}
|
}
|
||||||
light += strength;
|
light += strength;
|
||||||
|
dynamic_total += strength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (light > 1.0f) light = 1.0f;
|
if (light > 1.0f) light = 1.0f;
|
||||||
if (light < 0.0f) light = 0.0f;
|
if (light < 0.0f) light = 0.0f;
|
||||||
|
if (dynamic_total > 1.0f) dynamic_total = 1.0f;
|
||||||
|
|
||||||
|
if (uniforms && uniforms->fog_density > 0.0f) {
|
||||||
|
f32 dx = ctx->v_world.x - uniforms->camera_pos.x;
|
||||||
|
f32 dy = ctx->v_world.y - uniforms->camera_pos.y;
|
||||||
|
f32 dz = ctx->v_world.z - uniforms->camera_pos.z;
|
||||||
|
f32 dist_sq = dx * dx + dy * dy + dz * dz;
|
||||||
|
f32 fog = dist_sq * uniforms->fog_density * uniforms->fog_density;
|
||||||
|
if (fog > 1.0f) fog = 1.0f;
|
||||||
|
light *= (1.0f - fog);
|
||||||
|
light += dynamic_total * fog * 0.4f;
|
||||||
|
if (light > 1.0f) light = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
f32 light_f = light * 255.0f;
|
f32 light_f = light * 255.0f;
|
||||||
u8 light_u8 = (u8)light_f;
|
u8 light_u8 = (u8)light_f;
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,20 @@ pxl8.get_wireframe = gfx.get_wireframe
|
||||||
|
|
||||||
pxl8.Lights = effects.Lights
|
pxl8.Lights = effects.Lights
|
||||||
pxl8.create_lights = effects.Lights.new
|
pxl8.create_lights = effects.Lights.new
|
||||||
|
pxl8.Glows = effects.Glows
|
||||||
|
pxl8.create_glows = effects.Glows.new
|
||||||
|
pxl8.GLOW_CIRCLE = 0
|
||||||
|
pxl8.GLOW_DIAMOND = 1
|
||||||
|
pxl8.GLOW_SHAFT = 2
|
||||||
|
|
||||||
|
pxl8.LIGHT_WHITE = 0
|
||||||
|
pxl8.LIGHT_RED = 1
|
||||||
|
pxl8.LIGHT_ORANGE = 2
|
||||||
|
pxl8.LIGHT_YELLOW = 3
|
||||||
|
pxl8.LIGHT_GREEN = 4
|
||||||
|
pxl8.LIGHT_CYAN = 5
|
||||||
|
pxl8.LIGHT_BLUE = 6
|
||||||
|
pxl8.LIGHT_PURPLE = 7
|
||||||
|
|
||||||
pxl8.Compressor = sfx.Compressor
|
pxl8.Compressor = sfx.Compressor
|
||||||
pxl8.create_compressor = sfx.Compressor.new
|
pxl8.create_compressor = sfx.Compressor.new
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
local ffi = require("ffi")
|
local ffi = require("ffi")
|
||||||
local C = ffi.C
|
local C = ffi.C
|
||||||
|
local core = require("pxl8.core")
|
||||||
|
|
||||||
local effects = {}
|
local effects = {}
|
||||||
|
|
||||||
|
|
@ -35,4 +36,40 @@ end
|
||||||
|
|
||||||
effects.Lights = Lights
|
effects.Lights = Lights
|
||||||
|
|
||||||
|
local Glows = {}
|
||||||
|
Glows.__index = Glows
|
||||||
|
|
||||||
|
function Glows.new(capacity)
|
||||||
|
local ptr = C.pxl8_glows_create(capacity or 256)
|
||||||
|
if ptr == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return setmetatable({ _ptr = ptr }, Glows)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Glows:add(x, y, radius, intensity, color, shape, depth)
|
||||||
|
C.pxl8_glows_add(self._ptr, x, y, radius or 32, intensity or 128, color or 0, shape or 0, depth or 0xFFFF)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Glows:clear()
|
||||||
|
C.pxl8_glows_clear(self._ptr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Glows:count()
|
||||||
|
return C.pxl8_glows_count(self._ptr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Glows:render()
|
||||||
|
C.pxl8_glows_render(self._ptr, core.gfx)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Glows:destroy()
|
||||||
|
if self._ptr then
|
||||||
|
C.pxl8_glows_destroy(self._ptr)
|
||||||
|
self._ptr = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
effects.Glows = Glows
|
||||||
|
|
||||||
return effects
|
return effects
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ function Bsp:face_normal(face_id)
|
||||||
return C.pxl8_bsp_face_normal(self._ptr, face_id)
|
return C.pxl8_bsp_face_normal(self._ptr, face_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Bsp:light_at(x, y, z, ambient)
|
||||||
|
return C.pxl8_bsp_light_at(self._ptr, x, y, z, ambient or 0)
|
||||||
|
end
|
||||||
|
|
||||||
function Bsp:face_set_material(face_id, material_id)
|
function Bsp:face_set_material(face_id, material_id)
|
||||||
C.pxl8_bsp_face_set_material(self._ptr, face_id, material_id)
|
C.pxl8_bsp_face_set_material(self._ptr, face_id, material_id)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "pxl8_types.h"
|
#include "pxl8_types.h"
|
||||||
|
|
|
||||||
|
|
@ -220,8 +220,17 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"u32 pxl8_lights_count(const pxl8_lights* lights);\n"
|
"u32 pxl8_lights_count(const pxl8_lights* lights);\n"
|
||||||
"const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);\n"
|
"const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"typedef struct pxl8_glows pxl8_glows;\n"
|
||||||
|
"pxl8_glows* pxl8_glows_create(u32 capacity);\n"
|
||||||
|
"void pxl8_glows_destroy(pxl8_glows* glows);\n"
|
||||||
|
"void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape, u16 depth);\n"
|
||||||
|
"void pxl8_glows_clear(pxl8_glows* glows);\n"
|
||||||
|
"u32 pxl8_glows_count(const pxl8_glows* glows);\n"
|
||||||
|
"void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);\n"
|
||||||
|
"\n"
|
||||||
"typedef struct pxl8_3d_uniforms {\n"
|
"typedef struct pxl8_3d_uniforms {\n"
|
||||||
" u8 ambient;\n"
|
" u8 ambient;\n"
|
||||||
|
" pxl8_vec3 camera_pos;\n"
|
||||||
" pxl8_vec3 celestial_dir;\n"
|
" pxl8_vec3 celestial_dir;\n"
|
||||||
" f32 celestial_intensity;\n"
|
" f32 celestial_intensity;\n"
|
||||||
" u8 fog_color;\n"
|
" u8 fog_color;\n"
|
||||||
|
|
@ -392,6 +401,7 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"\n"
|
"\n"
|
||||||
"u32 pxl8_bsp_face_count(const pxl8_bsp* bsp);\n"
|
"u32 pxl8_bsp_face_count(const pxl8_bsp* bsp);\n"
|
||||||
"pxl8_vec3 pxl8_bsp_face_normal(const pxl8_bsp* bsp, u32 face_id);\n"
|
"pxl8_vec3 pxl8_bsp_face_normal(const pxl8_bsp* bsp, u32 face_id);\n"
|
||||||
|
"u8 pxl8_bsp_light_at(const pxl8_bsp* bsp, f32 x, f32 y, f32 z, u8 ambient);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"typedef enum { PXL8_WORLD_CHUNK_VXL = 0, PXL8_WORLD_CHUNK_BSP = 1 } pxl8_world_chunk_type;\n"
|
"typedef enum { PXL8_WORLD_CHUNK_VXL = 0, PXL8_WORLD_CHUNK_BSP = 1 } pxl8_world_chunk_type;\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue