From 5b6afd747fe2705c45d33e0767046550deeb87dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Wed, 28 Aug 2024 17:02:13 +0200 Subject: [PATCH] add: cubemap_sh_blend --- bind/v4k.lua | 1 + demos/09-envmap.c | 2 +- engine/joint/v4k.h | 28 ++++++++++++++++++++++++++++ engine/split/v4k_render.c | 25 +++++++++++++++++++++++++ engine/split/v4k_render.h | 3 +++ engine/v4k.c | 25 +++++++++++++++++++++++++ engine/v4k.h | 3 +++ 7 files changed, 86 insertions(+), 1 deletion(-) diff --git a/bind/v4k.lua b/bind/v4k.lua index ceaef18..d484d2a 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1128,6 +1128,7 @@ typedef struct cubemap_t { void cubemap_sh_reset(cubemap_t *c); void cubemap_sh_shader(cubemap_t *c); void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength); + void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes); unsigned fbo( unsigned texture_color, unsigned texture_depth, int wr_flags ); void fbo_bind(unsigned id); void fbo_unbind(); diff --git a/demos/09-envmap.c b/demos/09-envmap.c index 817d80a..5f01bc7 100644 --- a/demos/09-envmap.c +++ b/demos/09-envmap.c @@ -103,7 +103,7 @@ int main(int argc, char** argv) { skybox_render(&sky, cam.proj, cam.view); shader_bind(mdl.program); - shader_vec3v("u_coefficients_sh", 9, env_probe.cubemap.sh); + cubemap_sh_blend(vec3(0,0,0), 10.0f, 1, &env_probe.cubemap); shader_int("u_textured", false); model_render(mdl, cam.proj, cam.view, mdl.pivot, 0); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 636f5d6..c857456 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -17231,6 +17231,9 @@ API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_shader(cubemap_t *c); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength); +// lighting probe blending +API void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes); + // ----------------------------------------------------------------------------- // fbos @@ -383891,6 +383894,31 @@ void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength) { c->sh[3] = add3(c->sh[3], scale3(scaled_light, -0.488603f * norm_dir.x)); } +void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes) { + float total_weight = 0.0f; + vec3 final_sh[9] = {0}; + + // Iterate through each probe + for (unsigned i = 0; i < count; i++) { + float distance = len3(sub3(pos, probes[i].pos)); + float weight = 1.0f - (distance / max_dist); + weight = weight * weight; + + for (int s = 0; s < 9; s++) { + final_sh[s] = add3(final_sh[s], scale3(probes[i].sh[s], weight)); + } + + total_weight += weight; + } + + // Normalize the final SH coefficients + for (int s = 0; s < 9; s++) { + final_sh[s] = scale3(final_sh[s], 1.0f / total_weight); + } + + // Apply SH coefficients to the shader + shader_vec3v("u_coefficients_sh", 9, final_sh); +} // ----------------------------------------------------------------------------- // skyboxes diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index 7702afa..fad1957 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -2207,6 +2207,31 @@ void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength) { c->sh[3] = add3(c->sh[3], scale3(scaled_light, -0.488603f * norm_dir.x)); } +void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes) { + float total_weight = 0.0f; + vec3 final_sh[9] = {0}; + + // Iterate through each probe + for (unsigned i = 0; i < count; i++) { + float distance = len3(sub3(pos, probes[i].pos)); + float weight = 1.0f - (distance / max_dist); + weight = weight * weight; + + for (int s = 0; s < 9; s++) { + final_sh[s] = add3(final_sh[s], scale3(probes[i].sh[s], weight)); + } + + total_weight += weight; + } + + // Normalize the final SH coefficients + for (int s = 0; s < 9; s++) { + final_sh[s] = scale3(final_sh[s], 1.0f / total_weight); + } + + // Apply SH coefficients to the shader + shader_vec3v("u_coefficients_sh", 9, final_sh); +} // ----------------------------------------------------------------------------- // skyboxes diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index a2b6760..602b815 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -263,6 +263,9 @@ API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_shader(cubemap_t *c); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength); +// lighting probe blending +API void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes); + // ----------------------------------------------------------------------------- // fbos diff --git a/engine/v4k.c b/engine/v4k.c index 72b623c..9f2c3c4 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -19006,6 +19006,31 @@ void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength) { c->sh[3] = add3(c->sh[3], scale3(scaled_light, -0.488603f * norm_dir.x)); } +void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes) { + float total_weight = 0.0f; + vec3 final_sh[9] = {0}; + + // Iterate through each probe + for (unsigned i = 0; i < count; i++) { + float distance = len3(sub3(pos, probes[i].pos)); + float weight = 1.0f - (distance / max_dist); + weight = weight * weight; + + for (int s = 0; s < 9; s++) { + final_sh[s] = add3(final_sh[s], scale3(probes[i].sh[s], weight)); + } + + total_weight += weight; + } + + // Normalize the final SH coefficients + for (int s = 0; s < 9; s++) { + final_sh[s] = scale3(final_sh[s], 1.0f / total_weight); + } + + // Apply SH coefficients to the shader + shader_vec3v("u_coefficients_sh", 9, final_sh); +} // ----------------------------------------------------------------------------- // skyboxes diff --git a/engine/v4k.h b/engine/v4k.h index d662ca0..1a4ffae 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -3298,6 +3298,9 @@ API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_shader(cubemap_t *c); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength); +// lighting probe blending +API void cubemap_sh_blend(vec3 pos, float max_dist, unsigned count, cubemap_t *probes); + // ----------------------------------------------------------------------------- // fbos