add colored lighting back in via the colormap
This commit is contained in:
parent
01e6059dd1
commit
05b2849f16
9 changed files with 73 additions and 37 deletions
|
|
@ -349,11 +349,12 @@
|
|||
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 0xFFB888 light-intensity light-radius)
|
||||
(lights:add light-x light-y light-z 2 light-intensity light-radius)
|
||||
|
||||
(pxl8.push_target)
|
||||
(pxl8.begin_frame_3d camera lights {
|
||||
:ambient 25
|
||||
:dither true
|
||||
:fog_density 0.0
|
||||
:celestial_dir [0.5 -0.8 0.3]
|
||||
:celestial_intensity 0.3})
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ typedef struct {
|
|||
static const pxl8_rgb pxl8_light_colors[PXL8_LIGHT_COLORS] = {
|
||||
{255, 255, 255},
|
||||
{255, 64, 64},
|
||||
{255, 160, 64},
|
||||
{255, 192, 64},
|
||||
{255, 255, 64},
|
||||
{64, 255, 64},
|
||||
{64, 255, 255},
|
||||
|
|
|
|||
|
|
@ -33,16 +33,16 @@ void pxl8_lights_destroy(pxl8_lights* lights) {
|
|||
pxl8_free(lights);
|
||||
}
|
||||
|
||||
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
|
||||
(void)r; (void)g; (void)b;
|
||||
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 color, u8 intensity, f32 radius) {
|
||||
if (!lights || lights->count >= lights->capacity) return;
|
||||
|
||||
f32 radius_sq = radius * radius;
|
||||
pxl8_light* l = &lights->data[lights->count++];
|
||||
l->color = color;
|
||||
l->intensity = (f32)intensity / 255.0f;
|
||||
l->inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f;
|
||||
l->position = (pxl8_vec3){{x, y, z}};
|
||||
l->radius_sq = radius_sq;
|
||||
l->inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f;
|
||||
l->intensity = (f32)intensity / 255.0f;
|
||||
}
|
||||
|
||||
void pxl8_lights_clear(pxl8_lights* lights) {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@
|
|||
#define PXL8_LIGHTS_MAX 256
|
||||
|
||||
typedef struct pxl8_light {
|
||||
u8 color;
|
||||
f32 intensity;
|
||||
f32 inv_radius_sq;
|
||||
pxl8_vec3 position;
|
||||
f32 radius_sq;
|
||||
f32 inv_radius_sq;
|
||||
f32 intensity;
|
||||
} pxl8_light;
|
||||
|
||||
typedef struct pxl8_lights pxl8_lights;
|
||||
|
|
@ -21,7 +22,7 @@ extern "C" {
|
|||
pxl8_lights* pxl8_lights_create(u32 capacity);
|
||||
void pxl8_lights_destroy(pxl8_lights* lights);
|
||||
|
||||
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius);
|
||||
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 color, u8 intensity, f32 radius);
|
||||
void pxl8_lights_clear(pxl8_lights* lights);
|
||||
u32 pxl8_lights_count(const pxl8_lights* lights);
|
||||
const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);
|
||||
|
|
|
|||
|
|
@ -43,11 +43,22 @@ static inline u8 pxl8_sample_indexed(const pxl8_shader_bindings* b, pxl8_vec2 uv
|
|||
}
|
||||
}
|
||||
|
||||
static inline u8 pxl8_colormap_lookup(const pxl8_shader_bindings* b, u8 color, u8 light) {
|
||||
static inline u8 pxl8_colormap_lookup(const pxl8_shader_bindings* b, u8 color, u8 light_color, u8 intensity) {
|
||||
if (!b) return color;
|
||||
const u8* cm = b->colormap;
|
||||
if (!cm) return color;
|
||||
u32 row = light >> 5;
|
||||
u32 row = ((u32)light_color << 3) + (intensity >> 5);
|
||||
return cm[(row << 8) | (u32)color];
|
||||
}
|
||||
|
||||
static inline u8 pxl8_colormap_lookup_dithered(const pxl8_shader_bindings* b, u8 color, u8 light_color, u8 intensity, u32 x, u32 y) {
|
||||
if (!b) return color;
|
||||
const u8* cm = b->colormap;
|
||||
if (!cm) return color;
|
||||
u32 base_row = intensity >> 5;
|
||||
u32 frac = intensity & 31;
|
||||
u32 threshold = PXL8_BAYER_4X4[(y & 3) * 4 + (x & 3)] * 2;
|
||||
u32 row = ((u32)light_color << 3) + (frac > threshold && base_row < 7 ? base_row + 1 : base_row);
|
||||
return cm[(row << 8) | (u32)color];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
extern u8 pxl8_shader_lit(pxl8_shader_ctx* ctx, const pxl8_shader_bindings* bindings, const pxl8_shader_uniforms* uniforms);
|
||||
extern u8 pxl8_shader_unlit(pxl8_shader_ctx* ctx, const pxl8_shader_bindings* bindings, const pxl8_shader_uniforms* uniforms);
|
||||
extern void pxl8_shader_lit(const pxl8_shader_ctx* ctx, const pxl8_shader_bindings* bindings, const pxl8_shader_uniforms* uniforms, u8* colors_out);
|
||||
extern void pxl8_shader_unlit(const pxl8_shader_ctx* ctx, const pxl8_shader_bindings* bindings, const pxl8_shader_uniforms* uniforms, u8* colors_out);
|
||||
|
||||
void pxl8_shader_registry_init(void) {}
|
||||
void pxl8_shader_registry_reload(void) {}
|
||||
|
||||
pxl8_shader_fn pxl8_shader_registry_get(const char* name) {
|
||||
if (strcmp(name, "lit") == 0) return (pxl8_shader_fn)pxl8_shader_lit;
|
||||
if (strcmp(name, "unlit") == 0) return (pxl8_shader_fn)pxl8_shader_unlit;
|
||||
if (strcmp(name, "lit") == 0) return pxl8_shader_lit;
|
||||
if (strcmp(name, "unlit") == 0) return pxl8_shader_unlit;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ void pxl8_shader_lit(
|
|||
}
|
||||
|
||||
pxl8_f32_simd light = ctx->v_light;
|
||||
f32 max_strength[4] = {0, 0, 0, 0};
|
||||
u8 dominant_color[4] = {0, 0, 0, 0};
|
||||
|
||||
if (uniforms) {
|
||||
pxl8_f32_simd ambient = pxl8_f32_simd_set((f32)uniforms->ambient / 255.0f);
|
||||
|
|
@ -72,11 +74,32 @@ void pxl8_shader_lit(
|
|||
);
|
||||
falloff = pxl8_f32_simd_max(falloff, pxl8_f32_simd_zero());
|
||||
|
||||
if (uniforms->dither) {
|
||||
f32 falloff_arr[4];
|
||||
pxl8_f32_simd_store(falloff_arr, falloff);
|
||||
for (u32 j = 0; j < 4; j++) {
|
||||
if (falloff_arr[j] < 0.5f) {
|
||||
f32 threshold = (PXL8_BAYER_4X4[((u32)py[j] & 3) * 4 + ((u32)px[j] & 3)] + 0.5f) * (1.0f / 16.0f);
|
||||
if (falloff_arr[j] < threshold * 0.5f) falloff_arr[j] = 0.0f;
|
||||
}
|
||||
}
|
||||
falloff = pxl8_f32_simd_load(falloff_arr);
|
||||
}
|
||||
|
||||
pxl8_f32_simd strength = pxl8_f32_simd_mul(
|
||||
pxl8_f32_simd_mul(pxl8_f32_simd_set(l->intensity), falloff),
|
||||
ndotl
|
||||
);
|
||||
|
||||
f32 strength_arr[4];
|
||||
pxl8_f32_simd_store(strength_arr, strength);
|
||||
for (u32 j = 0; j < 4; j++) {
|
||||
if (strength_arr[j] > max_strength[j]) {
|
||||
max_strength[j] = strength_arr[j];
|
||||
dominant_color[j] = l->color;
|
||||
}
|
||||
}
|
||||
|
||||
light = pxl8_f32_simd_add(light, strength);
|
||||
}
|
||||
}
|
||||
|
|
@ -88,13 +111,12 @@ void pxl8_shader_lit(
|
|||
pxl8_f32_simd_store(light_arr, light_f);
|
||||
|
||||
for (u32 i = 0; i < ctx->color_count; i++) {
|
||||
u8 light_u8;
|
||||
u8 light_u8 = (u8)light_arr[i];
|
||||
if (uniforms && uniforms->dither) {
|
||||
light_u8 = pxl8_gfx_dither(light_arr[i], (u32)px[i], (u32)py[i]);
|
||||
colors_out[i] = pxl8_colormap_lookup_dithered(bindings, tex_idx[i], dominant_color[i], light_u8, (u32)px[i], (u32)py[i]);
|
||||
} else {
|
||||
light_u8 = (u8)light_arr[i];
|
||||
colors_out[i] = pxl8_colormap_lookup(bindings, tex_idx[i], dominant_color[i], light_u8);
|
||||
}
|
||||
colors_out[i] = pxl8_colormap_lookup(bindings, tex_idx[i], light_u8);
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
@ -111,6 +133,8 @@ void pxl8_shader_lit(
|
|||
}
|
||||
|
||||
f32 light = ctx->v_light;
|
||||
f32 max_strength = 0;
|
||||
u8 dominant_color = 0;
|
||||
|
||||
if (uniforms) {
|
||||
f32 ambient = (f32)uniforms->ambient / 255.0f;
|
||||
|
|
@ -143,8 +167,16 @@ void pxl8_shader_lit(
|
|||
|
||||
f32 falloff = 1.0f - dist_sq * l->inv_radius_sq;
|
||||
if (falloff <= 0.0f) continue;
|
||||
if (uniforms->dither && falloff < 0.5f) {
|
||||
f32 threshold = (PXL8_BAYER_4X4[((u32)ctx->y & 3) * 4 + ((u32)ctx->x & 3)] + 0.5f) * (1.0f / 16.0f);
|
||||
if (falloff < threshold * 0.5f) continue;
|
||||
}
|
||||
|
||||
f32 strength = l->intensity * falloff * ndotl;
|
||||
if (strength > max_strength) {
|
||||
max_strength = strength;
|
||||
dominant_color = l->color;
|
||||
}
|
||||
light += strength;
|
||||
}
|
||||
}
|
||||
|
|
@ -155,9 +187,9 @@ void pxl8_shader_lit(
|
|||
f32 light_f = light * 255.0f;
|
||||
u8 light_u8 = (u8)light_f;
|
||||
if (uniforms && uniforms->dither) {
|
||||
light_u8 = pxl8_gfx_dither(light_f, (u32)ctx->x, (u32)ctx->y);
|
||||
colors_out[0] = pxl8_colormap_lookup_dithered(bindings, tex_idx, dominant_color, light_u8, (u32)ctx->x, (u32)ctx->y);
|
||||
} else {
|
||||
colors_out[0] = pxl8_colormap_lookup(bindings, tex_idx, dominant_color, light_u8);
|
||||
}
|
||||
|
||||
colors_out[0] = pxl8_colormap_lookup(bindings, tex_idx, light_u8);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,16 +14,8 @@ function Lights.new(capacity)
|
|||
return setmetatable({ _ptr = ptr }, Lights)
|
||||
end
|
||||
|
||||
function Lights:add(x, y, z, r, g, b, intensity, radius)
|
||||
if r and r > 255 then
|
||||
local rgb = r
|
||||
intensity = g
|
||||
radius = b
|
||||
r = bit.band(bit.rshift(rgb, 16), 0xFF)
|
||||
g = bit.band(bit.rshift(rgb, 8), 0xFF)
|
||||
b = bit.band(rgb, 0xFF)
|
||||
end
|
||||
C.pxl8_lights_add(self._ptr, x, y, z, r or 255, g or 255, b or 255, intensity or 255, radius or 10)
|
||||
function Lights:add(x, y, z, color, intensity, radius)
|
||||
C.pxl8_lights_add(self._ptr, x, y, z, color or 0, intensity or 255, radius or 10)
|
||||
end
|
||||
|
||||
function Lights:clear()
|
||||
|
|
|
|||
|
|
@ -205,18 +205,17 @@ static const char* pxl8_ffi_cdefs =
|
|||
"typedef struct { float m[16]; } pxl8_mat4;\n"
|
||||
"\n"
|
||||
"typedef struct pxl8_light {\n"
|
||||
" pxl8_vec3 position;\n"
|
||||
" u8 color;\n"
|
||||
" f32 intensity;\n"
|
||||
" f32 inv_radius_sq;\n"
|
||||
" u8 r, g, b;\n"
|
||||
" u8 intensity;\n"
|
||||
" f32 radius;\n"
|
||||
" pxl8_vec3 position;\n"
|
||||
" f32 radius_sq;\n"
|
||||
"} pxl8_light;\n"
|
||||
"\n"
|
||||
"typedef struct pxl8_lights pxl8_lights;\n"
|
||||
"pxl8_lights* pxl8_lights_create(u32 capacity);\n"
|
||||
"void pxl8_lights_destroy(pxl8_lights* lights);\n"
|
||||
"void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius);\n"
|
||||
"void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 color, u8 intensity, f32 radius);\n"
|
||||
"void pxl8_lights_clear(pxl8_lights* lights);\n"
|
||||
"u32 pxl8_lights_count(const pxl8_lights* lights);\n"
|
||||
"const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue