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)))
|
r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase)))
|
||||||
light-radius (* 150 (+ 0.95 r1 r2))]
|
light-radius (* 150 (+ 0.95 r1 r2))]
|
||||||
(lights:clear)
|
(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.push_target)
|
||||||
(pxl8.begin_frame_3d camera lights {
|
(pxl8.begin_frame_3d camera lights {
|
||||||
:ambient 25
|
:ambient 25
|
||||||
|
:dither true
|
||||||
:fog_density 0.0
|
:fog_density 0.0
|
||||||
:celestial_dir [0.5 -0.8 0.3]
|
:celestial_dir [0.5 -0.8 0.3]
|
||||||
:celestial_intensity 0.3})
|
:celestial_intensity 0.3})
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ typedef struct {
|
||||||
static const pxl8_rgb pxl8_light_colors[PXL8_LIGHT_COLORS] = {
|
static const pxl8_rgb pxl8_light_colors[PXL8_LIGHT_COLORS] = {
|
||||||
{255, 255, 255},
|
{255, 255, 255},
|
||||||
{255, 64, 64},
|
{255, 64, 64},
|
||||||
{255, 160, 64},
|
{255, 192, 64},
|
||||||
{255, 255, 64},
|
{255, 255, 64},
|
||||||
{64, 255, 64},
|
{64, 255, 64},
|
||||||
{64, 255, 255},
|
{64, 255, 255},
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,16 @@ void pxl8_lights_destroy(pxl8_lights* lights) {
|
||||||
pxl8_free(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 pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 color, u8 intensity, f32 radius) {
|
||||||
(void)r; (void)g; (void)b;
|
|
||||||
if (!lights || lights->count >= lights->capacity) return;
|
if (!lights || lights->count >= lights->capacity) return;
|
||||||
|
|
||||||
f32 radius_sq = radius * radius;
|
f32 radius_sq = radius * radius;
|
||||||
pxl8_light* l = &lights->data[lights->count++];
|
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->position = (pxl8_vec3){{x, y, z}};
|
||||||
l->radius_sq = radius_sq;
|
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) {
|
void pxl8_lights_clear(pxl8_lights* lights) {
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@
|
||||||
#define PXL8_LIGHTS_MAX 256
|
#define PXL8_LIGHTS_MAX 256
|
||||||
|
|
||||||
typedef struct pxl8_light {
|
typedef struct pxl8_light {
|
||||||
|
u8 color;
|
||||||
|
f32 intensity;
|
||||||
|
f32 inv_radius_sq;
|
||||||
pxl8_vec3 position;
|
pxl8_vec3 position;
|
||||||
f32 radius_sq;
|
f32 radius_sq;
|
||||||
f32 inv_radius_sq;
|
|
||||||
f32 intensity;
|
|
||||||
} pxl8_light;
|
} pxl8_light;
|
||||||
|
|
||||||
typedef struct pxl8_lights pxl8_lights;
|
typedef struct pxl8_lights pxl8_lights;
|
||||||
|
|
@ -21,7 +22,7 @@ extern "C" {
|
||||||
pxl8_lights* pxl8_lights_create(u32 capacity);
|
pxl8_lights* pxl8_lights_create(u32 capacity);
|
||||||
void pxl8_lights_destroy(pxl8_lights* lights);
|
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);
|
void pxl8_lights_clear(pxl8_lights* lights);
|
||||||
u32 pxl8_lights_count(const pxl8_lights* lights);
|
u32 pxl8_lights_count(const pxl8_lights* lights);
|
||||||
const pxl8_light* pxl8_lights_data(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;
|
if (!b) return color;
|
||||||
const u8* cm = b->colormap;
|
const u8* cm = b->colormap;
|
||||||
if (!cm) return color;
|
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];
|
return cm[(row << 8) | (u32)color];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
extern u8 pxl8_shader_lit(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 u8 pxl8_shader_unlit(pxl8_shader_ctx* ctx, const pxl8_shader_bindings* bindings, const pxl8_shader_uniforms* uniforms);
|
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_init(void) {}
|
||||||
void pxl8_shader_registry_reload(void) {}
|
void pxl8_shader_registry_reload(void) {}
|
||||||
|
|
||||||
pxl8_shader_fn pxl8_shader_registry_get(const char* name) {
|
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, "lit") == 0) return pxl8_shader_lit;
|
||||||
if (strcmp(name, "unlit") == 0) return (pxl8_shader_fn)pxl8_shader_unlit;
|
if (strcmp(name, "unlit") == 0) return pxl8_shader_unlit;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ void pxl8_shader_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
pxl8_f32_simd light = ctx->v_light;
|
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) {
|
if (uniforms) {
|
||||||
pxl8_f32_simd ambient = pxl8_f32_simd_set((f32)uniforms->ambient / 255.0f);
|
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());
|
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 strength = pxl8_f32_simd_mul(
|
||||||
pxl8_f32_simd_mul(pxl8_f32_simd_set(l->intensity), falloff),
|
pxl8_f32_simd_mul(pxl8_f32_simd_set(l->intensity), falloff),
|
||||||
ndotl
|
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);
|
light = pxl8_f32_simd_add(light, strength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,13 +111,12 @@ void pxl8_shader_lit(
|
||||||
pxl8_f32_simd_store(light_arr, light_f);
|
pxl8_f32_simd_store(light_arr, light_f);
|
||||||
|
|
||||||
for (u32 i = 0; i < ctx->color_count; i++) {
|
for (u32 i = 0; i < ctx->color_count; i++) {
|
||||||
u8 light_u8;
|
u8 light_u8 = (u8)light_arr[i];
|
||||||
if (uniforms && uniforms->dither) {
|
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 {
|
} 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
|
#else
|
||||||
|
|
@ -111,6 +133,8 @@ void pxl8_shader_lit(
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 light = ctx->v_light;
|
f32 light = ctx->v_light;
|
||||||
|
f32 max_strength = 0;
|
||||||
|
u8 dominant_color = 0;
|
||||||
|
|
||||||
if (uniforms) {
|
if (uniforms) {
|
||||||
f32 ambient = (f32)uniforms->ambient / 255.0f;
|
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;
|
f32 falloff = 1.0f - dist_sq * l->inv_radius_sq;
|
||||||
if (falloff <= 0.0f) continue;
|
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;
|
f32 strength = l->intensity * falloff * ndotl;
|
||||||
|
if (strength > max_strength) {
|
||||||
|
max_strength = strength;
|
||||||
|
dominant_color = l->color;
|
||||||
|
}
|
||||||
light += strength;
|
light += strength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,9 +187,9 @@ void pxl8_shader_lit(
|
||||||
f32 light_f = light * 255.0f;
|
f32 light_f = light * 255.0f;
|
||||||
u8 light_u8 = (u8)light_f;
|
u8 light_u8 = (u8)light_f;
|
||||||
if (uniforms && uniforms->dither) {
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,8 @@ function Lights.new(capacity)
|
||||||
return setmetatable({ _ptr = ptr }, Lights)
|
return setmetatable({ _ptr = ptr }, Lights)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Lights:add(x, y, z, r, g, b, intensity, radius)
|
function Lights:add(x, y, z, color, intensity, radius)
|
||||||
if r and r > 255 then
|
C.pxl8_lights_add(self._ptr, x, y, z, color or 0, intensity or 255, radius or 10)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Lights:clear()
|
function Lights:clear()
|
||||||
|
|
|
||||||
|
|
@ -205,18 +205,17 @@ static const char* pxl8_ffi_cdefs =
|
||||||
"typedef struct { float m[16]; } pxl8_mat4;\n"
|
"typedef struct { float m[16]; } pxl8_mat4;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"typedef struct pxl8_light {\n"
|
"typedef struct pxl8_light {\n"
|
||||||
" pxl8_vec3 position;\n"
|
" u8 color;\n"
|
||||||
|
" f32 intensity;\n"
|
||||||
" f32 inv_radius_sq;\n"
|
" f32 inv_radius_sq;\n"
|
||||||
" u8 r, g, b;\n"
|
" pxl8_vec3 position;\n"
|
||||||
" u8 intensity;\n"
|
|
||||||
" f32 radius;\n"
|
|
||||||
" f32 radius_sq;\n"
|
" f32 radius_sq;\n"
|
||||||
"} pxl8_light;\n"
|
"} pxl8_light;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"typedef struct pxl8_lights pxl8_lights;\n"
|
"typedef struct pxl8_lights pxl8_lights;\n"
|
||||||
"pxl8_lights* pxl8_lights_create(u32 capacity);\n"
|
"pxl8_lights* pxl8_lights_create(u32 capacity);\n"
|
||||||
"void pxl8_lights_destroy(pxl8_lights* lights);\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"
|
"void pxl8_lights_clear(pxl8_lights* lights);\n"
|
||||||
"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"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue