improve sw renderer
This commit is contained in:
parent
415d424057
commit
39ee0fefb7
89 changed files with 9380 additions and 2307 deletions
4103
demo/mod/blendtable.fnl
Normal file
4103
demo/mod/blendtable.fnl
Normal file
File diff suppressed because it is too large
Load diff
1031
demo/mod/colormap.fnl
Normal file
1031
demo/mod/colormap.fnl
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,18 @@
|
|||
(local pxl8 (require :pxl8))
|
||||
(local effects (require :pxl8.effects))
|
||||
(local net (require :pxl8.net))
|
||||
|
||||
(local colormap (require :mod.colormap))
|
||||
(local menu (require :mod.menu))
|
||||
(local palette (require :mod.palette))
|
||||
(local sky (require :mod.sky))
|
||||
(local textures (require :mod.textures))
|
||||
|
||||
(local bob-amount 4.0)
|
||||
(local bob-speed 8.0)
|
||||
(local cam-smoothing 0.25)
|
||||
(local cell-size 64)
|
||||
(local cursor-sensitivity 0.008)
|
||||
(local cursor-sensitivity 0.010)
|
||||
(local gravity -800)
|
||||
(local grid-size 64)
|
||||
(local ground-y 64)
|
||||
|
|
@ -16,7 +21,7 @@
|
|||
(local land-squash-amount -4)
|
||||
(local max-pitch 1.5)
|
||||
(local move-speed 200)
|
||||
(local turn-speed 2.0)
|
||||
(local turn-speed 4.0)
|
||||
|
||||
(local sim-tick-rate 60)
|
||||
(local sim-dt (/ 1.0 sim-tick-rate))
|
||||
|
|
@ -32,10 +37,10 @@
|
|||
(var cam-yaw 0)
|
||||
(var cam-z 1000)
|
||||
(var camera nil)
|
||||
(var cursor-look? true)
|
||||
(var grounded? true)
|
||||
(var land-squash 0)
|
||||
(var light-time 0)
|
||||
(var real-time 0)
|
||||
(var network nil)
|
||||
(var smooth-cam-x 1000)
|
||||
(var smooth-cam-z 1000)
|
||||
|
|
@ -43,16 +48,148 @@
|
|||
(var world nil)
|
||||
(var fps-avg 0)
|
||||
(var fps-sample-count 0)
|
||||
(var fireball-mesh nil)
|
||||
(var last-dt 0.016)
|
||||
(var lights nil)
|
||||
|
||||
(local FIREBALL_COLOR 184)
|
||||
(local cursor-look? true)
|
||||
(local FIREBALL_COLOR 218)
|
||||
(local STONE_FLOOR_START 37)
|
||||
(local STONE_WALL_START 2)
|
||||
(local MOSS_COLOR 200)
|
||||
|
||||
(fn init-fireball-palette []
|
||||
(for [i 0 7]
|
||||
(let [t (/ i 7)
|
||||
r (math.floor (+ 0xFF (* t 0)))
|
||||
g (math.floor (+ 0x60 (* t (- 0xE0 0x60))))
|
||||
b (math.floor (+ 0x10 (* t (- 0x80 0x10))))]
|
||||
(pxl8.set_palette_rgb (+ FIREBALL_COLOR i) r g b))))
|
||||
(local trail-positions [])
|
||||
(local TRAIL_LENGTH 8)
|
||||
|
||||
(fn create-fireball-mesh []
|
||||
(let [verts []
|
||||
indices []
|
||||
radius 5
|
||||
rings 4
|
||||
segments 6
|
||||
core-color (+ FIREBALL_COLOR 6)
|
||||
spike-color (+ FIREBALL_COLOR 2)]
|
||||
|
||||
;; top pole
|
||||
(table.insert verts {:x 0 :y radius :z 0 :nx 0 :ny 1 :nz 0 :color core-color :light 255})
|
||||
|
||||
;; sphere rings
|
||||
(for [ring 1 (- rings 1)]
|
||||
(let [phi (* (/ ring rings) math.pi)
|
||||
sin-phi (math.sin phi)
|
||||
cos-phi (math.cos phi)
|
||||
y (* radius cos-phi)
|
||||
ring-radius (* radius sin-phi)]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [theta (* (/ seg segments) math.pi 2)
|
||||
x (* ring-radius (math.cos theta))
|
||||
z (* ring-radius (math.sin theta))
|
||||
nx (* sin-phi (math.cos theta))
|
||||
nz (* sin-phi (math.sin theta))]
|
||||
(table.insert verts {:x x :y y :z z :nx nx :ny cos-phi :nz nz :color core-color :light 255})))))
|
||||
|
||||
;; bottom pole
|
||||
(let [bottom-idx (length verts)]
|
||||
(table.insert verts {:x 0 :y (- radius) :z 0 :nx 0 :ny -1 :nz 0 :color core-color :light 255})
|
||||
|
||||
;; top cap triangles
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)]
|
||||
(table.insert indices 0)
|
||||
(table.insert indices (+ 1 next-seg))
|
||||
(table.insert indices (+ 1 seg))))
|
||||
|
||||
;; middle quads
|
||||
(for [ring 0 (- rings 3)]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)
|
||||
curr-row (+ 1 (* ring segments))
|
||||
next-row (+ 1 (* (+ ring 1) segments))]
|
||||
(table.insert indices (+ curr-row seg))
|
||||
(table.insert indices (+ curr-row next-seg))
|
||||
(table.insert indices (+ next-row seg))
|
||||
(table.insert indices (+ curr-row next-seg))
|
||||
(table.insert indices (+ next-row next-seg))
|
||||
(table.insert indices (+ next-row seg)))))
|
||||
|
||||
;; bottom cap triangles
|
||||
(let [last-ring-start (+ 1 (* (- rings 2) segments))]
|
||||
(for [seg 0 (- segments 1)]
|
||||
(let [next-seg (% (+ seg 1) segments)]
|
||||
(table.insert indices bottom-idx)
|
||||
(table.insert indices (+ last-ring-start seg))
|
||||
(table.insert indices (+ last-ring-start next-seg))))))
|
||||
|
||||
;; add spikes - evenly distributed using golden ratio
|
||||
(let [num-spikes 12
|
||||
spike-len 8
|
||||
base-size 1.2
|
||||
golden-ratio (/ (+ 1 (math.sqrt 5)) 2)]
|
||||
(for [i 0 (- num-spikes 1)]
|
||||
(let [;; fibonacci sphere distribution
|
||||
y (- 1 (* (/ i (- num-spikes 1)) 2))
|
||||
r-at-y (math.sqrt (- 1 (* y y)))
|
||||
theta (* math.pi 2 i golden-ratio)
|
||||
nx (* r-at-y (math.cos theta))
|
||||
ny y
|
||||
nz (* r-at-y (math.sin theta))
|
||||
;; tangent vectors for base
|
||||
tx (if (> (math.abs ny) 0.9) 1 0)
|
||||
ty (if (> (math.abs ny) 0.9) 0 1)
|
||||
tz 0
|
||||
;; cross product for perpendicular
|
||||
px (- (* ty nz) (* tz ny))
|
||||
py (- (* tz nx) (* tx nz))
|
||||
pz (- (* tx ny) (* ty nx))
|
||||
pl (math.sqrt (+ (* px px) (* py py) (* pz pz)))
|
||||
px (/ px pl) py (/ py pl) pz (/ pz pl)
|
||||
;; second perpendicular
|
||||
qx (- (* ny pz) (* nz py))
|
||||
qy (- (* nz px) (* nx pz))
|
||||
qz (- (* nx py) (* ny px))
|
||||
;; base center inside sphere
|
||||
bx (* radius 0.8 nx)
|
||||
by (* radius 0.8 ny)
|
||||
bz (* radius 0.8 nz)
|
||||
;; spike tip
|
||||
sx (* (+ radius spike-len) nx)
|
||||
sy (* (+ radius spike-len) ny)
|
||||
sz (* (+ radius spike-len) nz)
|
||||
base-idx (length verts)]
|
||||
;; 4 base vertices forming a square
|
||||
(table.insert verts {:x (+ bx (* base-size px) (* base-size qx))
|
||||
:y (+ by (* base-size py) (* base-size qy))
|
||||
:z (+ bz (* base-size pz) (* base-size qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* base-size px) (* (- base-size) qx))
|
||||
:y (+ by (* base-size py) (* (- base-size) qy))
|
||||
:z (+ bz (* base-size pz) (* (- base-size) qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* (- base-size) px) (* (- base-size) qx))
|
||||
:y (+ by (* (- base-size) py) (* (- base-size) qy))
|
||||
:z (+ bz (* (- base-size) pz) (* (- base-size) qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
(table.insert verts {:x (+ bx (* (- base-size) px) (* base-size qx))
|
||||
:y (+ by (* (- base-size) py) (* base-size qy))
|
||||
:z (+ bz (* (- base-size) pz) (* base-size qz))
|
||||
:nx nx :ny ny :nz nz :color core-color :light 255})
|
||||
;; spike tip
|
||||
(table.insert verts {:x sx :y sy :z sz :nx nx :ny ny :nz nz :color spike-color :light 255})
|
||||
;; 4 triangular faces of pyramid
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 1))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 1))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices (+ base-idx 4))
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 4)))))
|
||||
|
||||
(set fireball-mesh (pxl8.create_mesh verts indices))))
|
||||
|
||||
(var client-tick 0)
|
||||
(var last-processed-tick 0)
|
||||
|
|
@ -99,10 +236,22 @@
|
|||
|
||||
(values new-x new-z))
|
||||
(fn init []
|
||||
(pxl8.set_relative_mouse_mode true)
|
||||
(pxl8.set_palette palette 256)
|
||||
(pxl8.set_colormap colormap 16384)
|
||||
(for [i 0 7]
|
||||
(let [t (/ i 7)
|
||||
r 0xFF
|
||||
g (math.floor (+ 0x60 (* t (- 0xE0 0x60))))
|
||||
b (math.floor (+ 0x10 (* t (- 0x80 0x10))))]
|
||||
(pxl8.set_palette_rgb (+ FIREBALL_COLOR i) r g b)))
|
||||
(sky.update-gradient 1 2 6 6 10 18)
|
||||
(pxl8.update_palette_deps)
|
||||
(set camera (pxl8.create_camera_3d))
|
||||
(set world (pxl8.create_world))
|
||||
(set lights (pxl8.create_lights))
|
||||
(sky.generate-stars 12345)
|
||||
(init-fireball-palette)
|
||||
(create-fireball-mesh)
|
||||
|
||||
(set network (net.Net.new {:port 7777}))
|
||||
(when network
|
||||
|
|
@ -119,17 +268,9 @@
|
|||
:num_rooms 20})]
|
||||
(if (< result 0)
|
||||
(pxl8.error (.. "Failed to generate rooms - result: " result))
|
||||
(let [floor-tex (pxl8.procgen_tex {:name "floor"
|
||||
:seed 11111
|
||||
:width 64
|
||||
:height 64
|
||||
:base_color 19})
|
||||
wall-tex (pxl8.procgen_tex {:name "wall"
|
||||
:seed 12345
|
||||
:width 64
|
||||
:height 64
|
||||
:base_color 4})
|
||||
sky-tex (pxl8.create_texture [0] 1 1)]
|
||||
(let [floor-tex (textures.mossy-cobblestone 44444 STONE_FLOOR_START MOSS_COLOR)
|
||||
wall-tex (textures.ashlar-wall 55555 STONE_WALL_START MOSS_COLOR)
|
||||
sky-tex (pxl8.create_texture [0] 1 1)]
|
||||
|
||||
(let [result (world:apply_textures [
|
||||
{:name "floor"
|
||||
|
|
@ -193,6 +334,7 @@
|
|||
(store-position t cam-x cam-z hist.yaw))))))))))
|
||||
|
||||
(fn update [dt]
|
||||
(set last-dt dt)
|
||||
(let [fps (pxl8.get_fps)]
|
||||
(set fps-sample-count (+ fps-sample-count 1))
|
||||
(set fps-avg (+ (* fps-avg (/ (- fps-sample-count 1) fps-sample-count))
|
||||
|
|
@ -234,9 +376,9 @@
|
|||
(when (and (not cursor-look?) (pxl8.key_down "down"))
|
||||
(set cam-pitch (math.max (- max-pitch) (- cam-pitch (* turn-speed dt)))))
|
||||
(when (and (not cursor-look?) (pxl8.key_down "left"))
|
||||
(set cam-yaw (+ cam-yaw (* turn-speed dt))))
|
||||
(when (and (not cursor-look?) (pxl8.key_down "right"))
|
||||
(set cam-yaw (- cam-yaw (* turn-speed dt))))
|
||||
(when (and (not cursor-look?) (pxl8.key_down "right"))
|
||||
(set cam-yaw (+ cam-yaw (* turn-speed dt))))
|
||||
|
||||
(when network
|
||||
(let [(ok err) (pcall (fn []
|
||||
|
|
@ -287,7 +429,8 @@
|
|||
(let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)]
|
||||
(set bob-time (+ (* bob-time 0.8) (* target-phase 0.2))))))
|
||||
|
||||
(set light-time (+ light-time (* dt 0.15))))))
|
||||
(set light-time (+ light-time (* dt 0.5)))
|
||||
(set real-time (+ real-time dt)))))
|
||||
|
||||
(fn frame []
|
||||
(pxl8.clear 1)
|
||||
|
|
@ -316,77 +459,57 @@
|
|||
[0 1 0])
|
||||
(camera:set_perspective 1.047 aspect 1.0 4096.0)
|
||||
|
||||
(let [light-pulse (+ 0.7 (* 0.3 (math.sin (* light-time 2))))
|
||||
forward-x (- (math.sin cam-yaw))
|
||||
forward-z (- (math.cos cam-yaw))
|
||||
light-x (+ smooth-cam-x (* 150 forward-x) (* 50 (math.cos light-time)))
|
||||
light-z (+ smooth-cam-z (* 150 forward-z) (* 50 (math.sin light-time)))
|
||||
light-y (+ eye-y 30)]
|
||||
(pxl8.begin_frame_3d camera {
|
||||
:ambient 80
|
||||
(let [light-x (+ 1000 (* 50 (math.cos light-time)))
|
||||
light-z (+ 940 (* 50 (math.sin light-time)))
|
||||
light-y 80
|
||||
phase (+ (* light-x 0.01) 1.7)
|
||||
f1 (* 0.08 (math.sin (+ (* real-time 2.5) phase)))
|
||||
f2 (* 0.05 (math.sin (+ (* real-time 4.1) (* phase 0.7))))
|
||||
f3 (* 0.03 (math.sin (+ (* real-time 7.3) (* phase 1.2))))
|
||||
flicker (+ 0.92 f1 f2 f3)
|
||||
light-intensity (math.floor (math.max 0 (math.min 255 (* 255 flicker))))
|
||||
r1 (* 0.06 (math.sin (+ (* real-time 1.8) (* phase 0.5))))
|
||||
r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase)))
|
||||
light-radius (* 150 (+ 0.95 r1 r2))]
|
||||
(lights:clear)
|
||||
(lights:add light-x light-y light-z 255 200 150 light-intensity light-radius)
|
||||
(pxl8.begin_frame_3d camera lights {
|
||||
:ambient 30
|
||||
:fog_density 0.0
|
||||
:celestial_dir [0.5 -0.8 0.3]
|
||||
:celestial_intensity 0.5
|
||||
:lights [{:x light-x :y light-y :z light-z
|
||||
:r 255 :g 200 :b 150
|
||||
:intensity (* 255 light-pulse)
|
||||
:radius 400}]})
|
||||
:celestial_intensity 0.5})
|
||||
(pxl8.clear_depth)
|
||||
|
||||
(sky.update-gradient 1 2 6 6 10 18)
|
||||
(sky.render smooth-cam-x eye-y smooth-cam-z)
|
||||
(sky.render smooth-cam-x eye-y smooth-cam-z (menu.is-wireframe))
|
||||
(pxl8.clear_depth)
|
||||
|
||||
(world:set_wireframe (menu.is-wireframe) 15)
|
||||
(world:render [smooth-cam-x eye-y smooth-cam-z])
|
||||
|
||||
(pxl8.end_frame_3d)
|
||||
(when fireball-mesh
|
||||
(let [wire (menu.is-wireframe)]
|
||||
(pxl8.draw_mesh fireball-mesh {:x light-x :y light-y :z light-z
|
||||
:passthrough true
|
||||
:wireframe wire
|
||||
:emissive 1.0})))
|
||||
|
||||
(let [dx (- light-x smooth-cam-x)
|
||||
dy (- light-y eye-y)
|
||||
dz (- light-z smooth-cam-z)
|
||||
dist (math.sqrt (+ (* dx dx) (* dy dy) (* dz dz)))]
|
||||
(when (> dist 1)
|
||||
(let [inv-dist (/ 1 dist)
|
||||
dir-x (* dx inv-dist)
|
||||
dir-y (* dy inv-dist)
|
||||
dir-z (* dz inv-dist)
|
||||
cos-yaw (math.cos cam-yaw)
|
||||
sin-yaw (math.sin cam-yaw)
|
||||
cos-pitch (math.cos cam-pitch)
|
||||
sin-pitch (math.sin cam-pitch)
|
||||
rx (+ (* dir-x cos-yaw) (* dir-z sin-yaw))
|
||||
rz (+ (* (- dir-x) sin-yaw) (* dir-z cos-yaw))
|
||||
ry (- (* dir-y cos-pitch) (* rz sin-pitch))
|
||||
fz (+ (* dir-y sin-pitch) (* rz cos-pitch))]
|
||||
(when (> fz 0.01)
|
||||
(let [width (pxl8.get_width)
|
||||
height (pxl8.get_height)
|
||||
fov 1.047
|
||||
half-fov-tan (math.tan (* fov 0.5))
|
||||
ndc-x (/ rx (* fz half-fov-tan aspect))
|
||||
ndc-y (/ ry (* fz half-fov-tan))
|
||||
sx (math.floor (* (+ 1 ndc-x) 0.5 width))
|
||||
sy (math.floor (* (- 1 ndc-y) 0.5 height))
|
||||
screen-size (/ 400 dist)
|
||||
base-radius (math.max 2 (math.min 12 (math.floor screen-size)))
|
||||
pulse-int (math.floor (* 180 light-pulse))]
|
||||
(when (and (>= sx 0) (< sx width) (>= sy 0) (< sy height))
|
||||
(effects.glows [
|
||||
{:x sx :y sy :radius (+ base-radius 2) :intensity (/ pulse-int 5) :color (+ FIREBALL_COLOR 1) :shape effects.GLOW_CIRCLE}
|
||||
{:x sx :y sy :radius base-radius :intensity pulse-int :color (+ FIREBALL_COLOR 5) :shape effects.GLOW_DIAMOND}]))))))))
|
||||
(pxl8.end_frame_3d))
|
||||
|
||||
(sky.render-stars cam-yaw cam-pitch 1.0)
|
||||
(sky.render-stars smooth-cam-x eye-y smooth-cam-z 1.0 last-dt)
|
||||
|
||||
(let [cx (/ (pxl8.get_width) 2)
|
||||
cy (/ (pxl8.get_height) 2)
|
||||
crosshair-size 4
|
||||
red-color 18]
|
||||
(pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy red-color)
|
||||
(pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) red-color))
|
||||
crosshair-color 240
|
||||
text-color 251]
|
||||
(pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy crosshair-color)
|
||||
(pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) crosshair-color)
|
||||
|
||||
(pxl8.text (.. "fps: " (string.format "%.0f" fps-avg)) 5 5 12)
|
||||
(pxl8.text (.. "pos: " (string.format "%.0f" cam-x) ","
|
||||
(string.format "%.0f" cam-y) ","
|
||||
(string.format "%.0f" cam-z)) 5 15 12))))
|
||||
(pxl8.text (.. "fps: " (string.format "%.0f" fps-avg)) 5 5 text-color)
|
||||
(pxl8.text (.. "pos: " (string.format "%.0f" cam-x) ","
|
||||
(string.format "%.0f" cam-y) ","
|
||||
(string.format "%.0f" cam-z)) 5 15 text-color)))))
|
||||
|
||||
{:init init
|
||||
:update update
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
(local music (require :mod.music))
|
||||
|
||||
(var paused false)
|
||||
(var wireframe false)
|
||||
(var gui nil)
|
||||
|
||||
(fn init []
|
||||
|
|
@ -37,18 +38,22 @@
|
|||
(when gui
|
||||
(gui:begin_frame)
|
||||
|
||||
(pxl8.gui_window 200 100 240 180 "pxl8 demo")
|
||||
(pxl8.gui_window 200 100 240 200 "pxl8 demo")
|
||||
|
||||
(when (gui:button 1 215 145 210 32 "Resume")
|
||||
(when (gui:button 1 215 147 210 30 "Resume")
|
||||
(hide))
|
||||
|
||||
(let [music-label (if (music.is-playing) "Music: On" "Music: Off")]
|
||||
(when (gui:button 3 215 185 210 32 music-label)
|
||||
(when (gui:button 3 215 182 210 30 music-label)
|
||||
(if (music.is-playing)
|
||||
(music.stop)
|
||||
(music.start))))
|
||||
|
||||
(when (gui:button 2 215 225 210 32 "Quit")
|
||||
(let [wire-label (if wireframe "Wireframe: On" "Wireframe: Off")]
|
||||
(when (gui:button 4 215 217 210 30 wire-label)
|
||||
(set wireframe (not wireframe))))
|
||||
|
||||
(when (gui:button 2 215 252 210 30 "Quit")
|
||||
(pxl8.quit))
|
||||
|
||||
(if (gui:is_hovering)
|
||||
|
|
@ -58,6 +63,7 @@
|
|||
(gui:end_frame)))
|
||||
|
||||
{:is-paused (fn [] paused)
|
||||
:is-wireframe (fn [] wireframe)
|
||||
:toggle toggle
|
||||
:show show
|
||||
:hide hide
|
||||
|
|
|
|||
263
demo/mod/palette.fnl
Normal file
263
demo/mod/palette.fnl
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
(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
|
||||
287
demo/mod/sky.fnl
287
demo/mod/sky.fnl
|
|
@ -1,23 +1,32 @@
|
|||
(local ffi (require :ffi))
|
||||
(local pxl8 (require :pxl8))
|
||||
(local effects (require :pxl8.effects))
|
||||
|
||||
(local SKY_GRADIENT_START 144)
|
||||
(local SKY_GRADIENT_COUNT 16)
|
||||
(local sky-radius 900)
|
||||
(local sky-segments 16)
|
||||
(local sky-rings 16)
|
||||
(local max-theta (* math.pi 0.55))
|
||||
|
||||
(local STAR_COUNT 200)
|
||||
(local TINY_STAR_COUNT 5000)
|
||||
(local STAR_SILVER_START 160)
|
||||
(local STAR_BLUE_START 168)
|
||||
(local STAR_RED_START 176)
|
||||
(local NUM_RANDOM_STARS 300)
|
||||
(local NUM_TINY_STARS 7000)
|
||||
(local STAR_SEED 0xDEADBEEF)
|
||||
(local STAR_CYCLE_PERIOD 7200)
|
||||
|
||||
;; 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)
|
||||
|
||||
(var sky-mesh nil)
|
||||
(var last-gradient-key nil)
|
||||
(var stars [])
|
||||
(var random-stars [])
|
||||
(var sky-mesh nil)
|
||||
(var star-count 0)
|
||||
(var star-directions nil)
|
||||
(var star-glows nil)
|
||||
(var star-projected nil)
|
||||
(var star-time 0)
|
||||
(var tiny-stars [])
|
||||
|
||||
(fn generate-sky-gradient [zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b]
|
||||
|
|
@ -33,8 +42,8 @@
|
|||
indices []]
|
||||
|
||||
(for [i 0 (- sky-rings 1)]
|
||||
(let [theta0 (* (/ i sky-rings) max-theta)
|
||||
theta1 (* (/ (+ i 1) sky-rings) max-theta)
|
||||
(let [theta0 (* (/ i sky-rings) math.pi 0.5)
|
||||
theta1 (* (/ (+ i 1) sky-rings) math.pi 0.5)
|
||||
sin-t0 (math.sin theta0)
|
||||
cos-t0 (math.cos theta0)
|
||||
sin-t1 (math.sin theta1)
|
||||
|
|
@ -67,22 +76,17 @@
|
|||
|
||||
(if (= i 0)
|
||||
(do
|
||||
;; First ring is degenerate - just a triangle from pole
|
||||
;; Vertices: v00 (pole, c0), v11 (bottom-right, c1), v10 (bottom-left, c1)
|
||||
(table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255})
|
||||
(table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255})
|
||||
(table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255})
|
||||
;; Triangle: base, base+2, base+1
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 2))
|
||||
(table.insert indices (+ base-idx 1)))
|
||||
(do
|
||||
;; Regular quad: v00 (top-left), v01 (top-right), v11 (bottom-right), v10 (bottom-left)
|
||||
(table.insert verts {:x x00 :y y0 :z z00 :nx nx00 :ny ny00 :nz nz00 :color c0 :light 255})
|
||||
(table.insert verts {:x x01 :y y0 :z z01 :nx nx01 :ny ny01 :nz nz01 :color c0 :light 255})
|
||||
(table.insert verts {:x x11 :y y1 :z z11 :nx nx11 :ny ny11 :nz nz11 :color c1 :light 255})
|
||||
(table.insert verts {:x x10 :y y1 :z z10 :nx nx10 :ny ny10 :nz nz10 :color c1 :light 255})
|
||||
;; push_quad(base, base+3, base+2, base+1) = triangles (base,base+3,base+2) and (base,base+2,base+1)
|
||||
(table.insert indices base-idx)
|
||||
(table.insert indices (+ base-idx 3))
|
||||
(table.insert indices (+ base-idx 2))
|
||||
|
|
@ -98,149 +102,142 @@
|
|||
(generate-sky-gradient zenith-r zenith-g zenith-b horizon-r horizon-g horizon-b)
|
||||
(set last-gradient-key key))))
|
||||
|
||||
(fn palette-ramp [start c0 c1]
|
||||
(let [r0 (bit.rshift (bit.band c0 0xFF0000) 16)
|
||||
g0 (bit.rshift (bit.band c0 0x00FF00) 8)
|
||||
b0 (bit.band c0 0x0000FF)
|
||||
r1 (bit.rshift (bit.band c1 0xFF0000) 16)
|
||||
g1 (bit.rshift (bit.band c1 0x00FF00) 8)
|
||||
b1 (bit.band c1 0x0000FF)]
|
||||
(for [i 0 7]
|
||||
(let [t (/ i 7)
|
||||
r (math.floor (+ r0 (* t (- r1 r0))))
|
||||
g (math.floor (+ g0 (* t (- g1 g0))))
|
||||
b (math.floor (+ b0 (* t (- b1 b0))))]
|
||||
(pxl8.set_palette_rgb (+ start i) r g b)))))
|
||||
(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-from-band (math.abs (+ (* dx bx) (* dy by) (* dz bz)))
|
||||
in-band (- 1 (math.min (* dist-from-band 3) 1))]
|
||||
(* in-band in-band)))
|
||||
|
||||
(fn init-star-palette []
|
||||
(palette-ramp STAR_SILVER_START 0x707888 0xFFFFFF) ;; silver
|
||||
(palette-ramp STAR_BLUE_START 0x5070B0 0xD0E8FF) ;; blue
|
||||
(palette-ramp STAR_RED_START 0x802020 0xFF9090)) ;; red
|
||||
|
||||
(fn generate-stars [seed]
|
||||
(set stars [])
|
||||
(fn generate-stars []
|
||||
(set random-stars [])
|
||||
(set tiny-stars [])
|
||||
(init-star-palette)
|
||||
(pxl8.rng_seed seed)
|
||||
|
||||
(for [i 1 STAR_COUNT]
|
||||
(let [theta (math.acos (- 1 (* (pxl8.rng_f32) 0.85)))
|
||||
phi (* (pxl8.rng_f32) math.pi 2)
|
||||
brightness (pxl8.rng_range 1 4)
|
||||
color-type (pxl8.rng_range 0 100)
|
||||
shade (pxl8.rng_range 0 5)
|
||||
color (if (< color-type 3) (+ STAR_RED_START shade)
|
||||
(< color-type 15) (+ STAR_BLUE_START shade)
|
||||
(+ STAR_SILVER_START shade))
|
||||
sin-t (math.sin theta)
|
||||
cos-t (math.cos theta)]
|
||||
(table.insert stars {:dx (* sin-t (math.cos phi))
|
||||
:dy cos-t
|
||||
:dz (* sin-t (math.sin phi))
|
||||
:brightness brightness
|
||||
:color color})))
|
||||
;; 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)))]
|
||||
|
||||
(pxl8.rng_seed (+ seed 0xCAFEBABE))
|
||||
(for [i 1 TINY_STAR_COUNT]
|
||||
(let [theta (math.acos (- 1 (* (pxl8.rng_f32) 0.95)))
|
||||
phi (* (pxl8.rng_f32) math.pi 2)
|
||||
brightness (+ 25 (pxl8.rng_range 0 40))
|
||||
shade (pxl8.rng_range 0 3)
|
||||
color-type (pxl8.rng_range 0 100)
|
||||
color (if (< color-type 15) (+ STAR_BLUE_START shade)
|
||||
(+ STAR_SILVER_START shade))
|
||||
sin-t (math.sin theta)
|
||||
cos-t (math.cos theta)]
|
||||
(table.insert tiny-stars {:dx (* sin-t (math.cos phi))
|
||||
:dy cos-t
|
||||
:dz (* sin-t (math.sin phi))
|
||||
:brightness brightness
|
||||
:color color}))))
|
||||
(when (> dy -0.1)
|
||||
(table.insert random-stars {:dx dx :dy dy :dz dz
|
||||
:brightness brightness
|
||||
:color color}))))
|
||||
|
||||
(fn project-direction [dir-x dir-y dir-z yaw pitch width height]
|
||||
(let [cos-yaw (math.cos yaw)
|
||||
sin-yaw (math.sin yaw)
|
||||
cos-pitch (math.cos pitch)
|
||||
sin-pitch (math.sin pitch)
|
||||
rotated-x (+ (* dir-x cos-yaw) (* dir-z sin-yaw))
|
||||
rotated-z (+ (* (- dir-x) sin-yaw) (* dir-z cos-yaw))
|
||||
rotated-y (- (* dir-y cos-pitch) (* rotated-z sin-pitch))
|
||||
final-z (+ (* dir-y sin-pitch) (* rotated-z cos-pitch))]
|
||||
(when (> final-z 0.01)
|
||||
(let [fov 1.047
|
||||
aspect (/ width height)
|
||||
half-fov-tan (math.tan (* fov 0.5))
|
||||
ndc-x (/ rotated-x (* final-z half-fov-tan aspect))
|
||||
ndc-y (/ rotated-y (* final-z half-fov-tan))]
|
||||
(when (and (>= ndc-x -1) (<= ndc-x 1) (>= ndc-y -1) (<= ndc-y 1))
|
||||
{:x (math.floor (* (+ 1 ndc-x) 0.5 width))
|
||||
:y (math.floor (* (- 1 ndc-y) 0.5 height))})))))
|
||||
(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)))
|
||||
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))
|
||||
band-boost (galactic-band-factor dx dy dz)
|
||||
base-bright (+ 40 (% h3 50))
|
||||
brightness (+ base-bright (math.floor (* band-boost 40)))
|
||||
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})))))
|
||||
|
||||
(fn render-stars [yaw pitch intensity]
|
||||
(when (> intensity 0)
|
||||
(let [width (pxl8.get_width)
|
||||
height (pxl8.get_height)
|
||||
glows []
|
||||
fade-sq (* intensity intensity)]
|
||||
(set star-count (+ (length tiny-stars) (length random-stars)))
|
||||
(set star-directions (pxl8.create_vec3_array star-count))
|
||||
(set star-glows (pxl8.create_glows 10000))
|
||||
(set star-projected (pxl8.create_vec3_array star-count))
|
||||
|
||||
(each [_ star (ipairs tiny-stars)]
|
||||
(let [screen (project-direction star.dx star.dy star.dz yaw pitch width height)]
|
||||
(when screen
|
||||
(let [int (math.floor (* star.brightness fade-sq))]
|
||||
(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))))
|
||||
|
||||
(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)
|
||||
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)]
|
||||
|
||||
(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)
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 1
|
||||
:intensity int
|
||||
:color star.color
|
||||
:shape effects.GLOW_CIRCLE}))))))
|
||||
(star-glows:add (math.floor screen.x) (math.floor screen.y)
|
||||
1 int star.color pxl8.GLOW_CIRCLE))))))
|
||||
|
||||
(each [_ star (ipairs stars)]
|
||||
(let [screen (project-direction star.dx star.dy star.dz yaw pitch width height)]
|
||||
(when screen
|
||||
(let [base-int (math.floor (* star.brightness 50 fade-sq 1.5))]
|
||||
(if (>= star.brightness 4)
|
||||
(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)
|
||||
sy (math.floor screen.y)]
|
||||
(if (> star.brightness 220)
|
||||
(do
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 4
|
||||
:intensity (math.floor (/ base-int 4))
|
||||
:color star.color
|
||||
:shape effects.GLOW_CIRCLE})
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 2
|
||||
:intensity base-int
|
||||
:color star.color
|
||||
:shape effects.GLOW_DIAMOND}))
|
||||
(>= star.brightness 3)
|
||||
(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
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 3
|
||||
:intensity (math.floor (/ base-int 4))
|
||||
:color star.color
|
||||
:shape effects.GLOW_CIRCLE})
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 2
|
||||
:intensity base-int
|
||||
:color star.color
|
||||
:shape effects.GLOW_DIAMOND}))
|
||||
(>= star.brightness 2)
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 2
|
||||
:intensity base-int
|
||||
:color star.color
|
||||
:shape effects.GLOW_DIAMOND})
|
||||
(table.insert glows {:x screen.x :y screen.y
|
||||
:radius 1
|
||||
:intensity (math.floor (* base-int 0.7))
|
||||
:color star.color
|
||||
:shape effects.GLOW_CIRCLE}))))))
|
||||
(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 (> (length glows) 0)
|
||||
(effects.glows glows)))))
|
||||
(when (> (star-glows:count) 0)
|
||||
(star-glows:render)))))
|
||||
|
||||
(fn render [cam-x cam-y cam-z]
|
||||
(fn render [cam-x cam-y cam-z wireframe]
|
||||
(when (not sky-mesh) (create-sky-dome))
|
||||
(when sky-mesh
|
||||
(pxl8.draw_mesh sky-mesh {:x cam-x :y cam-y :z cam-z :passthrough true})))
|
||||
(pxl8.draw_mesh sky-mesh {:x cam-x :y cam-y :z cam-z :passthrough true :wireframe wireframe})))
|
||||
|
||||
{:render render
|
||||
:render-stars render-stars
|
||||
|
|
|
|||
168
demo/mod/textures.fnl
Normal file
168
demo/mod/textures.fnl
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
(local pxl8 (require :pxl8))
|
||||
(local procgen (require :pxl8.procgen))
|
||||
|
||||
(local textures {})
|
||||
|
||||
(fn build-graph [seed builder]
|
||||
(let [g (pxl8.create_graph 128)
|
||||
x (g:add_node procgen.OP_INPUT_X 0 0 0 0 0)
|
||||
y (g:add_node procgen.OP_INPUT_Y 0 0 0 0 0)
|
||||
ctx {:graph g :x x :y y}]
|
||||
(g:set_seed seed)
|
||||
(let [output (builder ctx)]
|
||||
(g:set_output output)
|
||||
g)))
|
||||
|
||||
(fn const [ctx val]
|
||||
(ctx.graph:add_node procgen.OP_CONST 0 0 0 0 val))
|
||||
|
||||
(fn add [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_ADD a b 0 0 0))
|
||||
|
||||
(fn sub [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_SUB a b 0 0 0))
|
||||
|
||||
(fn mul [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_MUL a b 0 0 0))
|
||||
|
||||
(fn div [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_DIV a b 0 0 0))
|
||||
|
||||
(fn min-op [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_MIN a b 0 0 0))
|
||||
|
||||
(fn max-op [ctx a b]
|
||||
(ctx.graph:add_node procgen.OP_MAX a b 0 0 0))
|
||||
|
||||
(fn abs [ctx a]
|
||||
(ctx.graph:add_node procgen.OP_ABS a 0 0 0 0))
|
||||
|
||||
(fn floor [ctx a]
|
||||
(ctx.graph:add_node procgen.OP_FLOOR a 0 0 0 0))
|
||||
|
||||
(fn fract [ctx a]
|
||||
(ctx.graph:add_node procgen.OP_FRACT a 0 0 0 0))
|
||||
|
||||
(fn lerp [ctx a b t]
|
||||
(ctx.graph:add_node procgen.OP_LERP a b t 0 0))
|
||||
|
||||
(fn clamp [ctx val lo hi]
|
||||
(ctx.graph:add_node procgen.OP_CLAMP val lo hi 0 0))
|
||||
|
||||
(fn select [ctx cond a b]
|
||||
(ctx.graph:add_node procgen.OP_SELECT a b cond 0 0))
|
||||
|
||||
(fn smoothstep [ctx edge0 edge1 x]
|
||||
(ctx.graph:add_node procgen.OP_SMOOTHSTEP edge0 edge1 x 0 0))
|
||||
|
||||
(fn noise-value [ctx scale]
|
||||
(let [s (const ctx scale)]
|
||||
(ctx.graph:add_node procgen.OP_NOISE_VALUE ctx.x ctx.y s 0 0)))
|
||||
|
||||
(fn noise-perlin [ctx scale]
|
||||
(let [s (const ctx scale)]
|
||||
(ctx.graph:add_node procgen.OP_NOISE_PERLIN ctx.x ctx.y s 0 0)))
|
||||
|
||||
(fn noise-fbm [ctx octaves scale persistence]
|
||||
(let [s (const ctx scale)
|
||||
p (const ctx persistence)]
|
||||
(ctx.graph:add_node procgen.OP_NOISE_FBM ctx.x ctx.y s p octaves)))
|
||||
|
||||
(fn noise-ridged [ctx octaves scale persistence]
|
||||
(let [s (const ctx scale)
|
||||
p (const ctx persistence)]
|
||||
(ctx.graph:add_node procgen.OP_NOISE_RIDGED ctx.x ctx.y s p octaves)))
|
||||
|
||||
(fn noise-turbulence [ctx octaves scale persistence]
|
||||
(let [s (const ctx scale)
|
||||
p (const ctx persistence)]
|
||||
(ctx.graph:add_node procgen.OP_NOISE_TURBULENCE ctx.x ctx.y s p octaves)))
|
||||
|
||||
(fn voronoi-cell [ctx scale]
|
||||
(let [s (const ctx scale)]
|
||||
(ctx.graph:add_node procgen.OP_VORONOI_CELL ctx.x ctx.y s 0 0)))
|
||||
|
||||
(fn voronoi-edge [ctx scale]
|
||||
(let [s (const ctx scale)]
|
||||
(ctx.graph:add_node procgen.OP_VORONOI_EDGE ctx.x ctx.y s 0 0)))
|
||||
|
||||
(fn voronoi-id [ctx scale]
|
||||
(let [s (const ctx scale)]
|
||||
(ctx.graph:add_node procgen.OP_VORONOI_ID ctx.x ctx.y s 0 0)))
|
||||
|
||||
(fn gradient-linear [ctx angle]
|
||||
(let [a (const ctx angle)]
|
||||
(ctx.graph:add_node procgen.OP_GRADIENT_LINEAR ctx.x ctx.y a 0 0)))
|
||||
|
||||
(fn gradient-radial [ctx cx cy]
|
||||
(let [center-x (const ctx cx)
|
||||
center-y (const ctx cy)]
|
||||
(ctx.graph:add_node procgen.OP_GRADIENT_RADIAL ctx.x ctx.y center-x center-y 0)))
|
||||
|
||||
(fn quantize [ctx val base range]
|
||||
(let [r (const ctx range)]
|
||||
(ctx.graph:add_node procgen.OP_QUANTIZE val r 0 0 base)))
|
||||
|
||||
(fn textures.mossy-cobblestone [seed base-color moss-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [cell (voronoi-cell ctx 6)
|
||||
edge (voronoi-edge ctx 6)
|
||||
mortar-threshold (const ctx 0.05)
|
||||
is-mortar (sub ctx mortar-threshold edge)
|
||||
mortar-color (const ctx (- base-color 2))
|
||||
stone-detail (noise-value ctx 48)
|
||||
stone-base (mul ctx cell (const ctx 0.6))
|
||||
stone-combined (add ctx stone-base (mul ctx stone-detail (const ctx 0.4)))
|
||||
stone-quant (quantize ctx stone-combined base-color 8)
|
||||
moss-pattern (noise-fbm ctx 4 10 0.5)
|
||||
moss-detail (noise-value ctx 64)
|
||||
moss-var (add ctx (mul ctx moss-pattern (const ctx 0.7))
|
||||
(mul ctx moss-detail (const ctx 0.3)))
|
||||
moss-threshold (const ctx 0.55)
|
||||
has-moss (sub ctx moss-pattern moss-threshold)
|
||||
moss-quant (quantize ctx moss-var moss-color 6)
|
||||
stone-or-moss (select ctx has-moss moss-quant stone-quant)]
|
||||
(select ctx is-mortar mortar-color stone-or-moss))))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
(fn textures.ashlar-wall [seed base-color moss-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [cell (voronoi-cell ctx 5)
|
||||
edge (voronoi-edge ctx 5)
|
||||
cell-id (voronoi-id ctx 5)
|
||||
mortar-threshold (const ctx 0.12)
|
||||
is-mortar (sub ctx mortar-threshold edge)
|
||||
stone-detail (noise-fbm ctx 3 32 0.5)
|
||||
stone-tint (mul ctx cell-id (const ctx 0.4))
|
||||
stone-shade (mul ctx cell (const ctx 0.3))
|
||||
stone-combined (add ctx stone-detail (add ctx stone-tint stone-shade))
|
||||
stone-quant (quantize ctx stone-combined base-color 10)
|
||||
crack-moss (noise-fbm ctx 3 16 0.5)
|
||||
moss-in-crack (mul ctx crack-moss (sub ctx (const ctx 0.2) edge))
|
||||
moss-threshold (const ctx 0.06)
|
||||
has-moss (sub ctx moss-in-crack moss-threshold)
|
||||
moss-quant (quantize ctx crack-moss moss-color 4)
|
||||
mortar-color (const ctx (+ base-color 1))
|
||||
stone-or-moss (select ctx has-moss moss-quant stone-quant)]
|
||||
(select ctx is-mortar mortar-color stone-or-moss))))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
(fn textures.gradient-sky [seed zenith-color horizon-color]
|
||||
(let [g (build-graph seed
|
||||
(fn [ctx]
|
||||
(let [grad (gradient-linear ctx (* math.pi 0.5))
|
||||
zenith (const ctx zenith-color)
|
||||
horizon (const ctx horizon-color)
|
||||
range (const ctx (- horizon-color zenith-color))]
|
||||
(quantize ctx grad zenith-color (- horizon-color zenith-color)))))]
|
||||
(let [tex-id (g:eval_texture 64 64)]
|
||||
(g:destroy)
|
||||
tex-id)))
|
||||
|
||||
textures
|
||||
Loading…
Add table
Add a link
Reference in a new issue