improve glow rendering

This commit is contained in:
asrael 2026-01-23 11:12:37 -06:00
parent 28c3e7ee04
commit 27c6fa628d
7 changed files with 145 additions and 48 deletions

View file

@ -1,5 +1,4 @@
(local pxl8 (require :pxl8)) (local pxl8 (require :pxl8))
(local effects (require :pxl8.effects))
(local SKY_GRADIENT_START 144) (local SKY_GRADIENT_START 144)
(local SKY_GRADIENT_COUNT 16) (local SKY_GRADIENT_COUNT 16)
@ -25,6 +24,7 @@
(var sky-mesh nil) (var sky-mesh nil)
(var star-count 0) (var star-count 0)
(var star-directions nil) (var star-directions nil)
(var star-glows nil)
(var star-projected nil) (var star-projected nil)
(var star-time 0) (var star-time 0)
(var tiny-stars []) (var tiny-stars [])
@ -167,6 +167,7 @@
(set star-count (+ (length tiny-stars) (length random-stars))) (set star-count (+ (length tiny-stars) (length random-stars)))
(set star-directions (pxl8.create_vec3_array star-count)) (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)) (set star-projected (pxl8.create_vec3_array star-count))
(var idx 0) (var idx 0)
@ -185,9 +186,8 @@
(fn render-stars [cam-x cam-y cam-z intensity dt] (fn render-stars [cam-x cam-y cam-z intensity dt]
(set star-time (+ star-time (or dt 0))) (set star-time (+ star-time (or dt 0)))
(when (and (> intensity 0) (> star-count 0)) (when (and (> intensity 0) (> star-count 0) star-glows)
(let [glows [] (let [fade-in (* intensity intensity)
fade-in (* intensity intensity)
time-factor (/ star-time 60) time-factor (/ star-time 60)
star-rotation (/ (* star-time math.pi 2) STAR_CYCLE_PERIOD) star-rotation (/ (* star-time math.pi 2) STAR_CYCLE_PERIOD)
t (pxl8.mat4_translate cam-x cam-y cam-z) t (pxl8.mat4_translate cam-x cam-y cam-z)
@ -196,6 +196,7 @@
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 (length tiny-stars)]
(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)] (for [i 0 (- tiny-count 1)]
@ -204,11 +205,8 @@
(let [star (. tiny-stars (+ i 1)) (let [star (. tiny-stars (+ i 1))
int (math.floor (* star.brightness fade-in))] int (math.floor (* star.brightness fade-in))]
(when (> int 8) (when (> int 8)
(table.insert glows {:x (math.floor screen.x) :y (math.floor screen.y) (star-glows:add (math.floor screen.x) (math.floor screen.y)
:radius 1 1 int star.color pxl8.GLOW_CIRCLE))))))
:intensity int
:color star.color
:shape effects.GLOW_CIRCLE}))))))
(for [i 0 (- (length random-stars) 1)] (for [i 0 (- (length random-stars) 1)]
(let [screen (. star-projected (+ tiny-count i))] (let [screen (. star-projected (+ tiny-count i))]
@ -221,33 +219,20 @@
sy (math.floor screen.y)] sy (math.floor screen.y)]
(if (> star.brightness 220) (if (> star.brightness 220)
(do (do
(table.insert glows {:x sx :y sy :radius 3 (star-glows:add sx sy 3 (math.floor (* int 1.5)) star.color pxl8.GLOW_DIAMOND)
:intensity (math.floor (* int 1.5)) (star-glows:add sx sy 5 (math.floor (/ int 2)) star.color pxl8.GLOW_CIRCLE))
:color star.color :shape effects.GLOW_DIAMOND})
(table.insert glows {:x sx :y sy :radius 5
:intensity (math.floor (/ int 2))
:color star.color :shape effects.GLOW_CIRCLE}))
(> star.brightness 180) (> star.brightness 180)
(do (do
(table.insert glows {:x sx :y sy :radius 2 :intensity int (star-glows:add sx sy 2 int star.color pxl8.GLOW_DIAMOND)
:color star.color :shape effects.GLOW_DIAMOND}) (star-glows:add sx sy 4 (math.floor (/ int 3)) star.color pxl8.GLOW_CIRCLE))
(table.insert glows {:x sx :y sy :radius 4
:intensity (math.floor (/ int 3))
:color star.color :shape effects.GLOW_CIRCLE}))
(> star.brightness 120) (> star.brightness 120)
(do (do
(table.insert glows {:x sx :y sy :radius 2 (star-glows:add sx sy 2 (math.floor (* int 0.67)) star.color pxl8.GLOW_DIAMOND)
:intensity (math.floor (* int 0.67)) (star-glows:add sx sy 3 (math.floor (/ int 4)) star.color pxl8.GLOW_CIRCLE))
:color star.color :shape effects.GLOW_DIAMOND}) (star-glows:add sx sy 2 (math.floor (* int 0.5)) star.color pxl8.GLOW_CIRCLE))))))
(table.insert glows {:x sx :y sy :radius 3
:intensity (math.floor (/ int 4))
:color star.color :shape effects.GLOW_CIRCLE}))
(table.insert glows {:x sx :y sy :radius 2
:intensity (math.floor (* int 0.5))
:color star.color :shape effects.GLOW_CIRCLE}))))))
(when (> (length glows) 0) (when (> (star-glows:count) 0)
(effects.glows glows))))) (star-glows:render)))))
(fn render [cam-x cam-y cam-z wireframe] (fn render [cam-x cam-y cam-z wireframe]
(when (not sky-mesh) (create-sky-dome)) (when (not sky-mesh) (create-sky-dome))

View file

@ -395,6 +395,7 @@ case "$COMMAND" in
src/gfx/pxl8_dither.c src/gfx/pxl8_dither.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_mesh.c src/gfx/pxl8_mesh.c
src/gfx/pxl8_palette.c src/gfx/pxl8_palette.c

59
src/gfx/pxl8_glows.c Normal file
View file

@ -0,0 +1,59 @@
#include "pxl8_glows.h"
#include <stdlib.h>
struct pxl8_glows {
pxl8_glow_source* data;
u32 capacity;
u32 count;
};
pxl8_glows* pxl8_glows_create(u32 capacity) {
pxl8_glows* glows = calloc(1, sizeof(pxl8_glows));
if (!glows) return NULL;
glows->data = calloc(capacity, sizeof(pxl8_glow_source));
if (!glows->data) {
free(glows);
return NULL;
}
glows->capacity = capacity;
glows->count = 0;
return glows;
}
void pxl8_glows_destroy(pxl8_glows* glows) {
if (!glows) return;
free(glows->data);
free(glows);
}
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) {
if (!glows || glows->count >= glows->capacity) return;
pxl8_glow_source* g = &glows->data[glows->count++];
g->x = x;
g->y = y;
g->radius = radius;
g->intensity = intensity;
g->color = color;
g->shape = shape;
g->depth = 0xFFFF;
g->height = 0;
}
void pxl8_glows_clear(pxl8_glows* glows) {
if (!glows) return;
glows->count = 0;
}
u32 pxl8_glows_count(const pxl8_glows* glows) {
return glows ? glows->count : 0;
}
void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx) {
if (!glows || !gfx || glows->count == 0) return;
pxl8_gfx_apply_effect(gfx, PXL8_GFX_EFFECT_GLOWS, glows->data, glows->count);
}

22
src/gfx/pxl8_glows.h Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include "pxl8_gfx.h"
#include "pxl8_types.h"
typedef struct pxl8_glows pxl8_glows;
#ifdef __cplusplus
extern "C" {
#endif
pxl8_glows* pxl8_glows_create(u32 capacity);
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_clear(pxl8_glows* glows);
u32 pxl8_glows_count(const pxl8_glows* glows);
void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);
#ifdef __cplusplus
}
#endif

View file

@ -1,6 +1,7 @@
local anim = require("pxl8.anim") local anim = require("pxl8.anim")
local bytes = require("pxl8.bytes") local bytes = require("pxl8.bytes")
local core = require("pxl8.core") local core = require("pxl8.core")
local effects = require("pxl8.effects")
local gfx2d = require("pxl8.gfx2d") local gfx2d = require("pxl8.gfx2d")
local gfx3d = require("pxl8.gfx3d") local gfx3d = require("pxl8.gfx3d")
local gui = require("pxl8.gui") local gui = require("pxl8.gui")
@ -98,6 +99,12 @@ pxl8.draw_mesh = gfx3d.draw_mesh
pxl8.end_frame_3d = gfx3d.end_frame pxl8.end_frame_3d = gfx3d.end_frame
pxl8.project_points = gfx3d.project_points pxl8.project_points = gfx3d.project_points
pxl8.GLOW_CIRCLE = effects.GLOW_CIRCLE
pxl8.GLOW_DIAMOND = effects.GLOW_DIAMOND
pxl8.GLOW_SHAFT = effects.GLOW_SHAFT
pxl8.Glows = effects.Glows
pxl8.create_glows = effects.Glows.new
pxl8.Compressor = sfx.Compressor pxl8.Compressor = sfx.Compressor
pxl8.create_compressor = sfx.Compressor.new pxl8.create_compressor = sfx.Compressor.new
pxl8.Delay = sfx.Delay pxl8.Delay = sfx.Delay

View file

@ -8,25 +8,40 @@ effects.GLOW_CIRCLE = 0
effects.GLOW_DIAMOND = 1 effects.GLOW_DIAMOND = 1
effects.GLOW_SHAFT = 2 effects.GLOW_SHAFT = 2
function effects.glows(glows) local Glows = {}
if not glows or #glows == 0 then return end Glows.__index = Glows
local count = #glows function Glows.new(capacity)
local glow_array = ffi.new("pxl8_glow_source[?]", count) local ptr = C.pxl8_glows_create(capacity or 1000)
if ptr == nil then
for i, g in ipairs(glows) do return nil
local idx = i - 1
glow_array[idx].x = g.x or 0
glow_array[idx].y = g.y or 0
glow_array[idx].radius = g.radius or 8
glow_array[idx].intensity = g.intensity or 255
glow_array[idx].color = g.color or 15
glow_array[idx].depth = g.depth or 0xFFFF
glow_array[idx].height = g.height or 0
glow_array[idx].shape = g.shape or 0
end end
return setmetatable({ _ptr = ptr }, Glows)
C.pxl8_gfx_apply_effect(core.gfx, C.PXL8_GFX_EFFECT_GLOWS, glow_array, count)
end end
function Glows:add(x, y, radius, intensity, color, shape)
C.pxl8_glows_add(self._ptr, x, y, radius or 8, intensity or 255, color or 15, shape or 0)
end
function Glows:clear()
C.pxl8_glows_clear(self._ptr)
end
function Glows:count()
return C.pxl8_glows_count(self._ptr)
end
function Glows:destroy()
if self._ptr then
C.pxl8_glows_destroy(self._ptr)
self._ptr = nil
end
end
function Glows:render()
C.pxl8_glows_render(self._ptr, core.gfx)
end
effects.Glows = Glows
return effects return effects

View file

@ -249,6 +249,14 @@ static const char* pxl8_ffi_cdefs =
"\n" "\n"
"void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count);\n" "void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count);\n"
"void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx);\n" "void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx);\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);\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"
"void pxl8_gfx_colormap_update(pxl8_gfx* gfx);\n" "void pxl8_gfx_colormap_update(pxl8_gfx* gfx);\n"
"\n" "\n"
"void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms);\n" "void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms);\n"