render: improve skybox_mie_calc_sh and add sky_intensity

main
Dominik Madarász 2023-09-11 15:16:16 +02:00
parent 5747b95739
commit b47c47df54
8 changed files with 120 additions and 27 deletions

View File

@ -44,10 +44,6 @@ int main(int argc, char** argv) {
sky = skybox(flag("--mie") ? 0 : SKY_DIRS[SKY_DIR], 0); sky = skybox(flag("--mie") ? 0 : SKY_DIRS[SKY_DIR], 0);
mdl = model(OBJ_MDLS[OBJ_MDL], 0); mdl = model(OBJ_MDLS[OBJ_MDL], 0);
// rotation44(mdl.pivot, 0, 1,0,0); // @fixme: -90,1,0,0 -> should we rotate SHMs as well? compensate rotation in shader? // rotation44(mdl.pivot, 0, 1,0,0); // @fixme: -90,1,0,0 -> should we rotate SHMs as well? compensate rotation in shader?
if (flag("--mie")) {
skybox_mie_calc_sh(&sky);
}
} }
// fps camera // fps camera
@ -63,6 +59,14 @@ int main(int argc, char** argv) {
// render // render
mat44 mvp; multiply44x2(mvp, cam.proj, cam.view); mat44 mvp; multiply44x2(mvp, cam.proj, cam.view);
{ {
if (flag("--mie")) {
// skybox_sh_reset(&sky);
skybox_mie_calc_sh(&sky, 4.0f);
// float x = cosf((float)window_time())*4;
// skybox_sh_add_light(&sky, vec3(0.3,0.3,0.3), vec3(0,1,0), 16*absf(cosf((float)window_time()*2))+2);
// skybox_sh_add_light(&sky, vec3(0.6,0,0), vec3(x,1,0), 2);
}
skybox_render(&sky, cam.proj, cam.view); skybox_render(&sky, cam.proj, cam.view);
shader_bind(mdl.program); shader_bind(mdl.program);

View File

@ -40,7 +40,7 @@ int main() {
if (flag("--mie") && sky_update_until <= window_time()) { if (flag("--mie") && sky_update_until <= window_time()) {
shader_bind(sky.program); shader_bind(sky.program);
shader_vec3("uSunPos", vec3(0, (cosf((float)window_time()*0.25)*0.3)+0.2, -1)); shader_vec3("uSunPos", vec3(0, (cosf((float)window_time()*0.25)*0.3)+0.2, -1));
skybox_mie_calc_sh(&sky); skybox_mie_calc_sh(&sky, 2.0f);
sky_update_until = window_time() + 0.02; sky_update_until = window_time() + 0.02;
} }

View File

@ -1189,6 +1189,12 @@ ffi.cdef([[
//lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe); //lcpp INF [0000] vec3: macro name but used as C declaration in:API vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe); //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe);
//lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe); //lcpp INF [0000] vec3: macro name but used as C declaration in: vec3 pose(bool forward, float curframe, int minframe, int maxframe, bool loop, float *opt_retframe);
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in: void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in: void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
//lcpp INF [0000] vec3: macro name but used as C declaration in:API void viewport_color3(vec3 color); //lcpp INF [0000] vec3: macro name but used as C declaration in:API void viewport_color3(vec3 color);
//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void viewport_color3(vec3 color); //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void viewport_color3(vec3 color);
//lcpp INF [0000] vec3: macro name but used as C declaration in: void viewport_color3(vec3 color); //lcpp INF [0000] vec3: macro name but used as C declaration in: void viewport_color3(vec3 color);
@ -2532,7 +2538,9 @@ unsigned char *pixels;
skybox_t skybox(const char *panorama_or_cubemap_folder, int flags); skybox_t skybox(const char *panorama_or_cubemap_folder, int flags);
int skybox_render(skybox_t *sky, mat44 proj, mat44 view); int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
void skybox_destroy(skybox_t *sky); void skybox_destroy(skybox_t *sky);
void skybox_mie_calc_sh(skybox_t *sky); void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity);
void skybox_sh_reset(skybox_t *sky);
void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view);
int skybox_pop_state(); int skybox_pop_state();
void viewport_color(uint32_t color); void viewport_color(uint32_t color);

View File

@ -16791,7 +16791,9 @@ typedef struct skybox_t {
API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags); API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags);
API int skybox_render(skybox_t *sky, mat44 proj, mat44 view); API int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
API void skybox_destroy(skybox_t *sky); API void skybox_destroy(skybox_t *sky);
API void skybox_mie_calc_sh(skybox_t *sky); API void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity);
API void skybox_sh_reset(skybox_t *sky);
API void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate
API int skybox_pop_state(); // @to deprecate API int skybox_pop_state(); // @to deprecate
@ -341727,15 +341729,19 @@ skybox_t skybox(const char *asset, int flags) {
return sky; return sky;
} }
void skybox_mie_calc_sh(skybox_t *sky) { void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
unsigned WIDTH = 1024, HEIGHT = 1024; unsigned WIDTH = 1024, HEIGHT = 1024;
int last_fb; int last_fb;
int vp[4]; int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp); glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels) if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3); sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) { if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
@ -341745,7 +341751,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]); glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sky->textures[i]); glBindTexture(GL_TEXTURE_2D, sky->textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -341767,7 +341773,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
skybox_render(sky, proj, view); skybox_render(sky, proj, view);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, sky->pixels); glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, sky->pixels);
// calculate SH coefficients (@ands) // calculate SH coefficients (@ands)
// copied from cubemap6 method // copied from cubemap6 method
@ -341776,7 +341782,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}}; const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16; int step = 16;
for (int y = 0; y < HEIGHT; y += step) { for (int y = 0; y < HEIGHT; y += step) {
unsigned char *p = (unsigned char*)sky->pixels + y * WIDTH * 3; unsigned float *p = (unsigned float*)sky->pixels + y * WIDTH * 3;
for (int x = 0; x < WIDTH; x += step) { for (int x = 0; x < WIDTH; x += step) {
vec3 n = add3( vec3 n = add3(
add3( add3(
@ -341784,7 +341790,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)), scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)),
skyDir[i]); // texelDirection; skyDir[i]); // texelDirection;
float l = len3(n); float l = len3(n);
vec3 light = scale3(vec3(p[0], p[1], p[2]), 1 / (255.0f * l * l * l)); // texelSolidAngle * texel_radiance; vec3 light = scale3(vec3(p[0], p[1], p[2]), (1 / (l * l * l)) * sky_intensity); // texelSolidAngle * texel_radiance;
n = norm3(n); n = norm3(n);
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f)); sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0)); sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0));
@ -341809,6 +341815,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glViewport(vp[0], vp[1], vp[2], vp[3]); glViewport(vp[0], vp[1], vp[2], vp[3]);
} }
void skybox_sh_reset(skybox_t *sky) {
for (int s = 0; s < 9; s++) {
sky->cubemap.sh[s] = vec3(0,0,0);
}
}
void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
// Normalize the direction
vec3 norm_dir = norm3(dir);
// Scale the light color and intensity
vec3 scaled_light = scale3(light, strength);
// Add light to the SH coefficients
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(scaled_light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(scaled_light, -0.488603f * norm_dir.y));
sky->cubemap.sh[2] = add3(sky->cubemap.sh[2], scale3(scaled_light, 0.488603f * norm_dir.z));
sky->cubemap.sh[3] = add3(sky->cubemap.sh[3], scale3(scaled_light, -0.488603f * norm_dir.x));
}
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) { int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
last_cubemap = &sky->cubemap; last_cubemap = &sky->cubemap;

View File

@ -2413,15 +2413,19 @@ skybox_t skybox(const char *asset, int flags) {
return sky; return sky;
} }
void skybox_mie_calc_sh(skybox_t *sky) { void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
unsigned WIDTH = 1024, HEIGHT = 1024; unsigned WIDTH = 1024, HEIGHT = 1024;
int last_fb; int last_fb;
int vp[4]; int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp); glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels) if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3); sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) { if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
@ -2431,7 +2435,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]); glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sky->textures[i]); glBindTexture(GL_TEXTURE_2D, sky->textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -2453,7 +2457,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
skybox_render(sky, proj, view); skybox_render(sky, proj, view);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, sky->pixels); glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, sky->pixels);
// calculate SH coefficients (@ands) // calculate SH coefficients (@ands)
// copied from cubemap6 method // copied from cubemap6 method
@ -2462,7 +2466,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}}; const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16; int step = 16;
for (int y = 0; y < HEIGHT; y += step) { for (int y = 0; y < HEIGHT; y += step) {
unsigned char *p = (unsigned char*)sky->pixels + y * WIDTH * 3; unsigned float *p = (unsigned float*)sky->pixels + y * WIDTH * 3;
for (int x = 0; x < WIDTH; x += step) { for (int x = 0; x < WIDTH; x += step) {
vec3 n = add3( vec3 n = add3(
add3( add3(
@ -2470,7 +2474,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)), scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)),
skyDir[i]); // texelDirection; skyDir[i]); // texelDirection;
float l = len3(n); float l = len3(n);
vec3 light = scale3(vec3(p[0], p[1], p[2]), 1 / (255.0f * l * l * l)); // texelSolidAngle * texel_radiance; vec3 light = scale3(vec3(p[0], p[1], p[2]), (1 / (l * l * l)) * sky_intensity); // texelSolidAngle * texel_radiance;
n = norm3(n); n = norm3(n);
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f)); sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0)); sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0));
@ -2495,6 +2499,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glViewport(vp[0], vp[1], vp[2], vp[3]); glViewport(vp[0], vp[1], vp[2], vp[3]);
} }
void skybox_sh_reset(skybox_t *sky) {
for (int s = 0; s < 9; s++) {
sky->cubemap.sh[s] = vec3(0,0,0);
}
}
void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
// Normalize the direction
vec3 norm_dir = norm3(dir);
// Scale the light color and intensity
vec3 scaled_light = scale3(light, strength);
// Add light to the SH coefficients
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(scaled_light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(scaled_light, -0.488603f * norm_dir.y));
sky->cubemap.sh[2] = add3(sky->cubemap.sh[2], scale3(scaled_light, 0.488603f * norm_dir.z));
sky->cubemap.sh[3] = add3(sky->cubemap.sh[3], scale3(scaled_light, -0.488603f * norm_dir.x));
}
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) { int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
last_cubemap = &sky->cubemap; last_cubemap = &sky->cubemap;

View File

@ -635,7 +635,9 @@ typedef struct skybox_t {
API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags); API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags);
API int skybox_render(skybox_t *sky, mat44 proj, mat44 view); API int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
API void skybox_destroy(skybox_t *sky); API void skybox_destroy(skybox_t *sky);
API void skybox_mie_calc_sh(skybox_t *sky); API void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity);
API void skybox_sh_reset(skybox_t *sky);
API void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate
API int skybox_pop_state(); // @to deprecate API int skybox_pop_state(); // @to deprecate

View File

@ -12637,15 +12637,19 @@ skybox_t skybox(const char *asset, int flags) {
return sky; return sky;
} }
void skybox_mie_calc_sh(skybox_t *sky) { void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
unsigned WIDTH = 1024, HEIGHT = 1024; unsigned WIDTH = 1024, HEIGHT = 1024;
int last_fb; int last_fb;
int vp[4]; int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp); glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels) if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3); sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) { if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
@ -12655,7 +12659,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]); glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sky->textures[i]); glBindTexture(GL_TEXTURE_2D, sky->textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
@ -12677,7 +12681,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
skybox_render(sky, proj, view); skybox_render(sky, proj, view);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, sky->pixels); glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, sky->pixels);
// calculate SH coefficients (@ands) // calculate SH coefficients (@ands)
// copied from cubemap6 method // copied from cubemap6 method
@ -12686,7 +12690,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}}; const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16; int step = 16;
for (int y = 0; y < HEIGHT; y += step) { for (int y = 0; y < HEIGHT; y += step) {
unsigned char *p = (unsigned char*)sky->pixels + y * WIDTH * 3; unsigned float *p = (unsigned float*)sky->pixels + y * WIDTH * 3;
for (int x = 0; x < WIDTH; x += step) { for (int x = 0; x < WIDTH; x += step) {
vec3 n = add3( vec3 n = add3(
add3( add3(
@ -12694,7 +12698,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)), scale3(skyY[i], -2.0f * (y / (HEIGHT - 1.0f)) + 1.0f)),
skyDir[i]); // texelDirection; skyDir[i]); // texelDirection;
float l = len3(n); float l = len3(n);
vec3 light = scale3(vec3(p[0], p[1], p[2]), 1 / (255.0f * l * l * l)); // texelSolidAngle * texel_radiance; vec3 light = scale3(vec3(p[0], p[1], p[2]), (1 / (l * l * l)) * sky_intensity); // texelSolidAngle * texel_radiance;
n = norm3(n); n = norm3(n);
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f)); sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0)); sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(light, -0.488603f * n.y * 2.0 / 3.0));
@ -12719,6 +12723,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glViewport(vp[0], vp[1], vp[2], vp[3]); glViewport(vp[0], vp[1], vp[2], vp[3]);
} }
void skybox_sh_reset(skybox_t *sky) {
for (int s = 0; s < 9; s++) {
sky->cubemap.sh[s] = vec3(0,0,0);
}
}
void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength) {
// Normalize the direction
vec3 norm_dir = norm3(dir);
// Scale the light color and intensity
vec3 scaled_light = scale3(light, strength);
// Add light to the SH coefficients
sky->cubemap.sh[0] = add3(sky->cubemap.sh[0], scale3(scaled_light, 0.282095f));
sky->cubemap.sh[1] = add3(sky->cubemap.sh[1], scale3(scaled_light, -0.488603f * norm_dir.y));
sky->cubemap.sh[2] = add3(sky->cubemap.sh[2], scale3(scaled_light, 0.488603f * norm_dir.z));
sky->cubemap.sh[3] = add3(sky->cubemap.sh[3], scale3(scaled_light, -0.488603f * norm_dir.x));
}
int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) { int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view) {
last_cubemap = &sky->cubemap; last_cubemap = &sky->cubemap;

View File

@ -2874,7 +2874,9 @@ typedef struct skybox_t {
API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags); API skybox_t skybox(const char *panorama_or_cubemap_folder, int flags);
API int skybox_render(skybox_t *sky, mat44 proj, mat44 view); API int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
API void skybox_destroy(skybox_t *sky); API void skybox_destroy(skybox_t *sky);
API void skybox_mie_calc_sh(skybox_t *sky); API void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity);
API void skybox_sh_reset(skybox_t *sky);
API void skybox_sh_add_light(skybox_t *sky, vec3 light, vec3 dir, float strength);
API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate API int skybox_push_state(skybox_t *sky, mat44 proj, mat44 view); // @to deprecate
API int skybox_pop_state(); // @to deprecate API int skybox_pop_state(); // @to deprecate