improve lighting system
This commit is contained in:
parent
27c6fa628d
commit
f18652dc97
15 changed files with 193 additions and 119 deletions
|
|
@ -71,8 +71,8 @@ static pxl8_light_result calc_vertex_light(
|
|||
if (sky_factor < 0.0f) sky_factor = 0.0f;
|
||||
intensity += sky_factor * frame->uniforms.celestial_intensity * 0.3f;
|
||||
|
||||
for (u32 i = 0; i < frame->uniforms.num_lights; i++) {
|
||||
const pxl8_light* light = &frame->uniforms.lights[i];
|
||||
for (u32 i = 0; i < frame->lights_count; i++) {
|
||||
const pxl8_light* light = &frame->lights[i];
|
||||
f32 contrib = calc_light_intensity(light, world_pos, normal);
|
||||
if (contrib > 0.0f) {
|
||||
intensity += contrib;
|
||||
|
|
@ -1329,7 +1329,7 @@ u32* pxl8_cpu_get_output(pxl8_cpu_backend* cpu) {
|
|||
|
||||
void pxl8_cpu_render_glows(
|
||||
pxl8_cpu_backend* cpu,
|
||||
const pxl8_glow_source* glows,
|
||||
const pxl8_glow* glows,
|
||||
u32 glow_count
|
||||
) {
|
||||
if (!cpu || cpu->target_stack_depth == 0) return;
|
||||
|
|
@ -1344,7 +1344,7 @@ void pxl8_cpu_render_glows(
|
|||
u32* light_accum = target->light_accum;
|
||||
|
||||
for (u32 gi = 0; gi < glow_count; gi++) {
|
||||
const pxl8_glow_source* glow = &glows[gi];
|
||||
const pxl8_glow* glow = &glows[gi];
|
||||
i32 cx = glow->x;
|
||||
i32 cy = glow->y;
|
||||
i32 radius = glow->radius;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ u32 pxl8_cpu_get_width(const pxl8_cpu_backend* cpu);
|
|||
|
||||
void pxl8_cpu_render_glows(
|
||||
pxl8_cpu_backend* cpu,
|
||||
const pxl8_glow_source* glows,
|
||||
const pxl8_glow* glows,
|
||||
u32 glow_count
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -607,10 +607,12 @@ pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_3d_camera* camera, const pxl8
|
|||
return frame;
|
||||
}
|
||||
|
||||
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms) {
|
||||
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_lights* lights, const pxl8_3d_uniforms* uniforms) {
|
||||
if (!gfx || !camera) return;
|
||||
|
||||
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
|
||||
frame.lights = lights ? pxl8_lights_data(lights) : NULL;
|
||||
frame.lights_count = lights ? pxl8_lights_count(lights) : 0;
|
||||
|
||||
pxl8_mat4 vp = pxl8_mat4_multiply(frame.projection, frame.view);
|
||||
|
||||
|
|
@ -802,7 +804,7 @@ void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* pa
|
|||
|
||||
switch (effect) {
|
||||
case PXL8_GFX_EFFECT_GLOWS: {
|
||||
const pxl8_glow_source* glows = (const pxl8_glow_source*)params;
|
||||
const pxl8_glow* glows = (const pxl8_glow*)params;
|
||||
switch (gfx->backend.type) {
|
||||
case PXL8_GFX_BACKEND_CPU:
|
||||
pxl8_cpu_render_glows(gfx->backend.cpu, glows, count);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "pxl8_gfx2d.h"
|
||||
#include "pxl8_gfx3d.h"
|
||||
#include "pxl8_glows.h"
|
||||
#include "pxl8_hal.h"
|
||||
#include "pxl8_colormap.h"
|
||||
#include "pxl8_palette.h"
|
||||
|
|
@ -14,53 +15,6 @@ typedef enum pxl8_gfx_effect {
|
|||
PXL8_GFX_EFFECT_GLOWS = 0,
|
||||
} pxl8_gfx_effect;
|
||||
|
||||
#define PXL8_MAX_GLOWS 256
|
||||
|
||||
typedef enum pxl8_glow_shape {
|
||||
PXL8_GLOW_CIRCLE = 0,
|
||||
PXL8_GLOW_DIAMOND = 1,
|
||||
PXL8_GLOW_SHAFT = 2,
|
||||
} pxl8_glow_shape;
|
||||
|
||||
typedef struct pxl8_glow_source {
|
||||
u8 color;
|
||||
u16 depth;
|
||||
u8 height;
|
||||
u16 intensity;
|
||||
u8 radius;
|
||||
pxl8_glow_shape shape;
|
||||
i16 x;
|
||||
i16 y;
|
||||
} pxl8_glow_source;
|
||||
|
||||
static inline pxl8_glow_source pxl8_glow_create(i32 x, i32 y, u8 radius, u16 intensity, u8 color) {
|
||||
return (pxl8_glow_source){
|
||||
.color = color,
|
||||
.depth = 0xFFFF,
|
||||
.height = 0,
|
||||
.intensity = intensity,
|
||||
.radius = radius,
|
||||
.shape = PXL8_GLOW_CIRCLE,
|
||||
.x = (i16)x,
|
||||
.y = (i16)y,
|
||||
};
|
||||
}
|
||||
|
||||
static inline pxl8_glow_source pxl8_glow_with_depth(pxl8_glow_source g, u16 depth) {
|
||||
g.depth = depth;
|
||||
return g;
|
||||
}
|
||||
|
||||
static inline pxl8_glow_source pxl8_glow_with_shape(pxl8_glow_source g, pxl8_glow_shape shape) {
|
||||
g.shape = shape;
|
||||
return g;
|
||||
}
|
||||
|
||||
static inline pxl8_glow_source pxl8_glow_with_height(pxl8_glow_source g, u8 height) {
|
||||
g.height = height;
|
||||
return g;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,53 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "pxl8_3d_camera.h"
|
||||
#include "pxl8_lights.h"
|
||||
#include "pxl8_math.h"
|
||||
#include "pxl8_mesh.h"
|
||||
#include "pxl8_types.h"
|
||||
|
||||
typedef struct pxl8_gfx pxl8_gfx;
|
||||
|
||||
#define PXL8_MAX_LIGHTS 16
|
||||
|
||||
typedef struct pxl8_light {
|
||||
pxl8_vec3 position;
|
||||
u8 r, g, b;
|
||||
u8 intensity;
|
||||
f32 radius;
|
||||
f32 radius_sq;
|
||||
f32 inv_radius_sq;
|
||||
} pxl8_light;
|
||||
|
||||
static inline pxl8_light pxl8_light_create(pxl8_vec3 pos, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
|
||||
f32 radius_sq = radius * radius;
|
||||
return (pxl8_light){
|
||||
.position = pos,
|
||||
.r = r, .g = g, .b = b,
|
||||
.intensity = intensity,
|
||||
.radius = radius,
|
||||
.radius_sq = radius_sq,
|
||||
.inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f,
|
||||
};
|
||||
}
|
||||
|
||||
typedef struct pxl8_3d_uniforms {
|
||||
u8 ambient;
|
||||
pxl8_vec3 celestial_dir;
|
||||
f32 celestial_intensity;
|
||||
u8 fog_color;
|
||||
f32 fog_density;
|
||||
pxl8_light lights[PXL8_MAX_LIGHTS];
|
||||
u32 num_lights;
|
||||
f32 time;
|
||||
} pxl8_3d_uniforms;
|
||||
|
||||
typedef struct pxl8_3d_frame {
|
||||
pxl8_3d_uniforms uniforms;
|
||||
pxl8_vec3 camera_dir;
|
||||
pxl8_vec3 camera_pos;
|
||||
f32 far_clip;
|
||||
const pxl8_light* lights;
|
||||
u32 lights_count;
|
||||
f32 near_clip;
|
||||
pxl8_mat4 projection;
|
||||
pxl8_3d_uniforms uniforms;
|
||||
pxl8_mat4 view;
|
||||
} pxl8_3d_frame;
|
||||
|
||||
|
|
@ -55,7 +33,7 @@ typedef struct pxl8_3d_frame {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms);
|
||||
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_lights* lights, const pxl8_3d_uniforms* uniforms);
|
||||
void pxl8_3d_clear(pxl8_gfx* gfx, u8 color);
|
||||
void pxl8_3d_clear_depth(pxl8_gfx* gfx);
|
||||
void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#include "pxl8_glows.h"
|
||||
|
||||
#include "pxl8_gfx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct pxl8_glows {
|
||||
pxl8_glow_source* data;
|
||||
pxl8_glow* data;
|
||||
u32 capacity;
|
||||
u32 count;
|
||||
};
|
||||
|
|
@ -12,7 +14,7 @@ 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));
|
||||
glows->data = calloc(capacity, sizeof(pxl8_glow));
|
||||
if (!glows->data) {
|
||||
free(glows);
|
||||
return NULL;
|
||||
|
|
@ -33,7 +35,7 @@ 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) {
|
||||
if (!glows || glows->count >= glows->capacity) return;
|
||||
|
||||
pxl8_glow_source* g = &glows->data[glows->count++];
|
||||
pxl8_glow* g = &glows->data[glows->count++];
|
||||
g->x = x;
|
||||
g->y = y;
|
||||
g->radius = radius;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "pxl8_gfx.h"
|
||||
#include "pxl8_types.h"
|
||||
|
||||
#define PXL8_GLOWS_MAX 16384
|
||||
|
||||
typedef enum pxl8_glow_shape {
|
||||
PXL8_GLOW_CIRCLE = 0,
|
||||
PXL8_GLOW_DIAMOND = 1,
|
||||
PXL8_GLOW_SHAFT = 2,
|
||||
} pxl8_glow_shape;
|
||||
|
||||
typedef struct pxl8_glow {
|
||||
u8 color;
|
||||
u16 depth;
|
||||
u8 height;
|
||||
u16 intensity;
|
||||
u8 radius;
|
||||
pxl8_glow_shape shape;
|
||||
i16 x;
|
||||
i16 y;
|
||||
} pxl8_glow;
|
||||
|
||||
typedef struct pxl8_gfx pxl8_gfx;
|
||||
typedef struct pxl8_glows pxl8_glows;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -15,6 +34,7 @@ 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);
|
||||
const pxl8_glow* pxl8_glows_data(const pxl8_glows* glows);
|
||||
void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
63
src/gfx/pxl8_lights.c
Normal file
63
src/gfx/pxl8_lights.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "pxl8_lights.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct pxl8_lights {
|
||||
pxl8_light* data;
|
||||
u32 capacity;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
pxl8_lights* pxl8_lights_create(u32 capacity) {
|
||||
if (capacity > PXL8_LIGHTS_MAX) capacity = PXL8_LIGHTS_MAX;
|
||||
|
||||
pxl8_lights* lights = calloc(1, sizeof(pxl8_lights));
|
||||
if (!lights) return NULL;
|
||||
|
||||
lights->data = calloc(capacity, sizeof(pxl8_light));
|
||||
if (!lights->data) {
|
||||
free(lights);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lights->capacity = capacity;
|
||||
lights->count = 0;
|
||||
|
||||
return lights;
|
||||
}
|
||||
|
||||
void pxl8_lights_destroy(pxl8_lights* lights) {
|
||||
if (!lights) return;
|
||||
free(lights->data);
|
||||
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) {
|
||||
if (!lights || lights->count >= lights->capacity) return;
|
||||
|
||||
f32 radius_sq = radius * radius;
|
||||
pxl8_light* l = &lights->data[lights->count++];
|
||||
l->position.x = x;
|
||||
l->position.y = y;
|
||||
l->position.z = z;
|
||||
l->r = r;
|
||||
l->g = g;
|
||||
l->b = b;
|
||||
l->intensity = intensity;
|
||||
l->radius = radius;
|
||||
l->radius_sq = radius_sq;
|
||||
l->inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f;
|
||||
}
|
||||
|
||||
void pxl8_lights_clear(pxl8_lights* lights) {
|
||||
if (!lights) return;
|
||||
lights->count = 0;
|
||||
}
|
||||
|
||||
u32 pxl8_lights_count(const pxl8_lights* lights) {
|
||||
return lights ? lights->count : 0;
|
||||
}
|
||||
|
||||
const pxl8_light* pxl8_lights_data(const pxl8_lights* lights) {
|
||||
return lights ? lights->data : NULL;
|
||||
}
|
||||
33
src/gfx/pxl8_lights.h
Normal file
33
src/gfx/pxl8_lights.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "pxl8_math.h"
|
||||
#include "pxl8_types.h"
|
||||
|
||||
#define PXL8_LIGHTS_MAX 256
|
||||
|
||||
typedef struct pxl8_light {
|
||||
pxl8_vec3 position;
|
||||
f32 inv_radius_sq;
|
||||
u8 r, g, b;
|
||||
u8 intensity;
|
||||
f32 radius;
|
||||
f32 radius_sq;
|
||||
} pxl8_light;
|
||||
|
||||
typedef struct pxl8_lights pxl8_lights;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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_clear(pxl8_lights* lights);
|
||||
u32 pxl8_lights_count(const pxl8_lights* lights);
|
||||
const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue