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);
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?
if (flag("--mie")) {
skybox_mie_calc_sh(&sky);
}
}
// fps camera
@ -63,6 +59,14 @@ int main(int argc, char** argv) {
// render
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);
shader_bind(mdl.program);

View File

@ -40,7 +40,7 @@ int main() {
if (flag("--mie") && sky_update_until <= window_time()) {
shader_bind(sky.program);
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;
}

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: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: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:STATIC 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);
int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
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_pop_state();
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 int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
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_pop_state(); // @to deprecate
@ -341727,15 +341729,19 @@ skybox_t skybox(const char *asset, int flags) {
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;
int last_fb;
int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3);
sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) {
@ -341745,7 +341751,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0);
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_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
@ -341767,7 +341773,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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)
// 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}};
int step = 16;
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) {
vec3 n = 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)),
skyDir[i]); // texelDirection;
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);
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));
@ -341809,6 +341815,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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) {
last_cubemap = &sky->cubemap;

View File

@ -2413,15 +2413,19 @@ skybox_t skybox(const char *asset, int flags) {
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;
int last_fb;
int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3);
sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) {
@ -2431,7 +2435,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0);
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_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
@ -2453,7 +2457,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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)
// 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}};
int step = 16;
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) {
vec3 n = 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)),
skyDir[i]); // texelDirection;
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);
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));
@ -2495,6 +2499,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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) {
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 int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
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_pop_state(); // @to deprecate

View File

@ -12637,15 +12637,19 @@ skybox_t skybox(const char *asset, int flags) {
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;
int last_fb;
int vp[4];
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &last_fb);
glGetIntegerv(GL_VIEWPORT, vp);
if (!sky_intensity) {
sky_intensity = 1.0f;
}
if (!sky->pixels)
sky->pixels = MALLOC(WIDTH*HEIGHT*3);
sky->pixels = MALLOC(WIDTH*HEIGHT*12);
if (!sky->framebuffers[0]) {
for(int i = 0; i < 6; ++i) {
@ -12655,7 +12659,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
glGenTextures(1, &sky->textures[i]);
glActiveTexture(GL_TEXTURE0);
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_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
@ -12677,7 +12681,7 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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)
// 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}};
int step = 16;
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) {
vec3 n = 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)),
skyDir[i]); // texelDirection;
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);
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));
@ -12719,6 +12723,27 @@ void skybox_mie_calc_sh(skybox_t *sky) {
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) {
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 int skybox_render(skybox_t *sky, mat44 proj, mat44 view);
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_pop_state(); // @to deprecate