improve cubemap baking

main
Dominik Madarász 2024-08-28 16:41:47 +02:00
parent 61b94ed225
commit f7090441c0
7 changed files with 81 additions and 39 deletions

View File

@ -1124,7 +1124,7 @@ typedef struct cubemap_t {
cubemap_t* cubemap_get_active(); cubemap_t* cubemap_get_active();
void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height); void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height);
bool cubemap_bake_step(cubemap_t *c, mat44 proj , mat44 view ); bool cubemap_bake_step(cubemap_t *c, mat44 proj , mat44 view );
void cubemap_bake_end(cubemap_t *c, float sky_intensity); void cubemap_bake_end(cubemap_t *c, int step , float sky_intensity );
void cubemap_sh_reset(cubemap_t *c); void cubemap_sh_reset(cubemap_t *c);
void cubemap_sh_shader(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_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength);

View File

@ -82,7 +82,7 @@ int main(int argc, char** argv) {
if (follow_cam) { if (follow_cam) {
probe_pos = cam.position; probe_pos = cam.position;
} }
unsigned tex_size = 256; unsigned tex_size = 128;
cubemap_bake_begin(&env_probe.cubemap, probe_pos, tex_size, tex_size); cubemap_bake_begin(&env_probe.cubemap, probe_pos, tex_size, tex_size);
while (cubemap_bake_step(&env_probe.cubemap, probe_proj, probe_view)) { while (cubemap_bake_step(&env_probe.cubemap, probe_proj, probe_view)) {
skybox_render(&sky, probe_proj, probe_view); skybox_render(&sky, probe_proj, probe_view);
@ -91,7 +91,7 @@ int main(int argc, char** argv) {
model_render(mdl, probe_proj, probe_view, mdl.pivot, 0); model_render(mdl, probe_proj, probe_view, mdl.pivot, 0);
} }
cubemap_bake_end(&env_probe.cubemap, 1.2f); cubemap_bake_end(&env_probe.cubemap, 8, 1.0f);
} }
ddraw_sphere(probe_pos, 0.1f); ddraw_sphere(probe_pos, 0.1f);

View File

@ -17226,7 +17226,7 @@ API void cubemap_destroy(cubemap_t *c);
API cubemap_t* cubemap_get_active(); API cubemap_t* cubemap_get_active();
API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height); API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height);
API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */); API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */);
API void cubemap_bake_end(cubemap_t *c, float sky_intensity); API void cubemap_bake_end(cubemap_t *c, int step /* = 16 */, float sky_intensity /* = 1.0f */);
API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_reset(cubemap_t *c);
API void cubemap_sh_shader(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); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength);
@ -383647,7 +383647,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
c->width = width; c->width = width;
c->height = height; c->height = height;
if (!c->framebuffers[0]) { if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers); glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures); glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers); glDeleteRenderbuffers(6, c->depth_buffers);
@ -383661,7 +383661,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
glGenFramebuffers(1, &c->framebuffers[i]); glGenFramebuffers(1, &c->framebuffers[i]);
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
glGenTextures(1, &c->textures[i]); glGenTextures(1, &c->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, c->textures[i]); glBindTexture(GL_TEXTURE_2D, c->textures[i]);
@ -383686,24 +383686,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
if (c->step >= 6) return false; if (c->step >= 6) return false;
static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
static vec3 up_vectors[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
glClearDepth(1.0f); glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, c->width, c->height);
perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f); perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f);
lookat44(view, c->pos, add3(c->pos, directions[c->step]), vec3(0,-1,0)); lookat44(view, c->pos, add3(c->pos, directions[c->step]), up_vectors[c->step]);
++c->step; ++c->step;
return true; return true;
} }
void cubemap_bake_end(cubemap_t *c, float sky_intensity) { void cubemap_bake_end(cubemap_t *c, int step, float sky_intensity) {
if (!sky_intensity) { if (!sky_intensity) {
sky_intensity = 1.0f; sky_intensity = 1.0f;
} }
if (!step) {
step = 16;
}
if (c->id) { if (c->id) {
glDeleteTextures(1, &c->id); glDeleteTextures(1, &c->id);
@ -383796,6 +383801,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
#else #else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0; int samples = 0;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
@ -383807,8 +383815,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
// copied from cubemap6 method // copied from cubemap6 method
const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}}; const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}};
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; static vec3 skyY[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
for (int y = 0; y < c->height; y += step) { for (int y = 0; y < c->height; y += step) {
float *p = (float*)(c->pixels + y * c->width * 3); float *p = (float*)(c->pixels + y * c->width * 3);
for (int x = 0; x < c->width; x += step) { for (int x = 0; x < c->width; x += step) {
@ -383839,8 +383848,12 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
c->sh[s] = scale3(c->sh[s], 32.f / samples); c->sh[s] = scale3(c->sh[s], 32.f / samples);
} }
glGenTextures(1, &c->id); // Copy each face of the cubemap to the cubemap texture
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id); // for (int i = 0; i < 6; ++i) {
// glCopyImageSubData(c->textures[i], GL_TEXTURE_2D, 0, 0, 0, 0,
// c->id, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, 0,
// c->width, c->height, 1);
// }
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -384028,7 +384041,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
while (cubemap_bake_step(&sky->cubemap, proj, view)) { while (cubemap_bake_step(&sky->cubemap, proj, view)) {
skybox_render_rayleigh(sky, proj, view); skybox_render_rayleigh(sky, proj, view);
} }
cubemap_bake_end(&sky->cubemap, sky_intensity); cubemap_bake_end(&sky->cubemap, 0, sky_intensity);
} }
void skybox_sh_reset(skybox_t *sky) { void skybox_sh_reset(skybox_t *sky) {
@ -384088,6 +384101,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
} }
void skybox_destroy(skybox_t *sky) { void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program); glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap); cubemap_destroy(&sky->cubemap);
mesh_destroy(&sky->geometry); mesh_destroy(&sky->geometry);
} }

View File

@ -1963,7 +1963,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
c->width = width; c->width = width;
c->height = height; c->height = height;
if (!c->framebuffers[0]) { if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers); glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures); glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers); glDeleteRenderbuffers(6, c->depth_buffers);
@ -1977,7 +1977,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
glGenFramebuffers(1, &c->framebuffers[i]); glGenFramebuffers(1, &c->framebuffers[i]);
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
glGenTextures(1, &c->textures[i]); glGenTextures(1, &c->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, c->textures[i]); glBindTexture(GL_TEXTURE_2D, c->textures[i]);
@ -2002,24 +2002,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
if (c->step >= 6) return false; if (c->step >= 6) return false;
static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
static vec3 up_vectors[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
glClearDepth(1.0f); glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, c->width, c->height);
perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f); perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f);
lookat44(view, c->pos, add3(c->pos, directions[c->step]), vec3(0,-1,0)); lookat44(view, c->pos, add3(c->pos, directions[c->step]), up_vectors[c->step]);
++c->step; ++c->step;
return true; return true;
} }
void cubemap_bake_end(cubemap_t *c, float sky_intensity) { void cubemap_bake_end(cubemap_t *c, int step, float sky_intensity) {
if (!sky_intensity) { if (!sky_intensity) {
sky_intensity = 1.0f; sky_intensity = 1.0f;
} }
if (!step) {
step = 16;
}
if (c->id) { if (c->id) {
glDeleteTextures(1, &c->id); glDeleteTextures(1, &c->id);
@ -2112,6 +2117,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
#else #else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0; int samples = 0;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
@ -2123,8 +2131,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
// copied from cubemap6 method // copied from cubemap6 method
const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}}; const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}};
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; static vec3 skyY[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
for (int y = 0; y < c->height; y += step) { for (int y = 0; y < c->height; y += step) {
float *p = (float*)(c->pixels + y * c->width * 3); float *p = (float*)(c->pixels + y * c->width * 3);
for (int x = 0; x < c->width; x += step) { for (int x = 0; x < c->width; x += step) {
@ -2155,8 +2164,12 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
c->sh[s] = scale3(c->sh[s], 32.f / samples); c->sh[s] = scale3(c->sh[s], 32.f / samples);
} }
glGenTextures(1, &c->id); // Copy each face of the cubemap to the cubemap texture
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id); // for (int i = 0; i < 6; ++i) {
// glCopyImageSubData(c->textures[i], GL_TEXTURE_2D, 0, 0, 0, 0,
// c->id, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, 0,
// c->width, c->height, 1);
// }
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -2344,7 +2357,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
while (cubemap_bake_step(&sky->cubemap, proj, view)) { while (cubemap_bake_step(&sky->cubemap, proj, view)) {
skybox_render_rayleigh(sky, proj, view); skybox_render_rayleigh(sky, proj, view);
} }
cubemap_bake_end(&sky->cubemap, sky_intensity); cubemap_bake_end(&sky->cubemap, 0, sky_intensity);
} }
void skybox_sh_reset(skybox_t *sky) { void skybox_sh_reset(skybox_t *sky) {
@ -2404,6 +2417,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
} }
void skybox_destroy(skybox_t *sky) { void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program); glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap); cubemap_destroy(&sky->cubemap);
mesh_destroy(&sky->geometry); mesh_destroy(&sky->geometry);
} }

View File

@ -258,7 +258,7 @@ API void cubemap_destroy(cubemap_t *c);
API cubemap_t* cubemap_get_active(); API cubemap_t* cubemap_get_active();
API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height); API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height);
API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */); API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */);
API void cubemap_bake_end(cubemap_t *c, float sky_intensity); API void cubemap_bake_end(cubemap_t *c, int step /* = 16 */, float sky_intensity /* = 1.0f */);
API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_reset(cubemap_t *c);
API void cubemap_sh_shader(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); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength);

View File

@ -18762,7 +18762,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
c->width = width; c->width = width;
c->height = height; c->height = height;
if (!c->framebuffers[0]) { if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers); glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures); glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers); glDeleteRenderbuffers(6, c->depth_buffers);
@ -18776,7 +18776,7 @@ void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height)
for(int i = 0; i < 6; ++i) { for(int i = 0; i < 6; ++i) {
glGenFramebuffers(1, &c->framebuffers[i]); glGenFramebuffers(1, &c->framebuffers[i]);
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
glGenTextures(1, &c->textures[i]); glGenTextures(1, &c->textures[i]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, c->textures[i]); glBindTexture(GL_TEXTURE_2D, c->textures[i]);
@ -18801,24 +18801,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
if (c->step >= 6) return false; if (c->step >= 6) return false;
static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; static vec3 directions[6] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
static vec3 up_vectors[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[c->step]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
glClearDepth(1.0f); glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, c->width, c->height);
perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f); perspective44(proj, 90.0f, c->width / (float)c->height, 0.1f, 1000.f);
lookat44(view, c->pos, add3(c->pos, directions[c->step]), vec3(0,-1,0)); lookat44(view, c->pos, add3(c->pos, directions[c->step]), up_vectors[c->step]);
++c->step; ++c->step;
return true; return true;
} }
void cubemap_bake_end(cubemap_t *c, float sky_intensity) { void cubemap_bake_end(cubemap_t *c, int step, float sky_intensity) {
if (!sky_intensity) { if (!sky_intensity) {
sky_intensity = 1.0f; sky_intensity = 1.0f;
} }
if (!step) {
step = 16;
}
if (c->id) { if (c->id) {
glDeleteTextures(1, &c->id); glDeleteTextures(1, &c->id);
@ -18911,6 +18916,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
#else #else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0; int samples = 0;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, c->framebuffers[i]);
@ -18922,8 +18930,9 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
// copied from cubemap6 method // copied from cubemap6 method
const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}}; const vec3 skyDir[] = {{ 1, 0, 0},{-1, 0, 0},{ 0, 1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1}};
const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}}; const vec3 skyX[] = {{ 0, 0,-1},{ 0, 0, 1},{ 1, 0, 0},{ 1, 0, 0},{ 1, 0, 0},{-1, 0, 0}};
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; static vec3 skyY[6] = {{ 0,-1, 0},{ 0,-1, 0},{ 0, 0, 1},{ 0, 0,-1},{ 0,-1, 0},{ 0,-1, 0}};
for (int y = 0; y < c->height; y += step) { for (int y = 0; y < c->height; y += step) {
float *p = (float*)(c->pixels + y * c->width * 3); float *p = (float*)(c->pixels + y * c->width * 3);
for (int x = 0; x < c->width; x += step) { for (int x = 0; x < c->width; x += step) {
@ -18954,8 +18963,12 @@ void cubemap_bake_end(cubemap_t *c, float sky_intensity) {
c->sh[s] = scale3(c->sh[s], 32.f / samples); c->sh[s] = scale3(c->sh[s], 32.f / samples);
} }
glGenTextures(1, &c->id); // Copy each face of the cubemap to the cubemap texture
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id); // for (int i = 0; i < 6; ++i) {
// glCopyImageSubData(c->textures[i], GL_TEXTURE_2D, 0, 0, 0, 0,
// c->id, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, 0,
// c->width, c->height, 1);
// }
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -19143,7 +19156,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) {
while (cubemap_bake_step(&sky->cubemap, proj, view)) { while (cubemap_bake_step(&sky->cubemap, proj, view)) {
skybox_render_rayleigh(sky, proj, view); skybox_render_rayleigh(sky, proj, view);
} }
cubemap_bake_end(&sky->cubemap, sky_intensity); cubemap_bake_end(&sky->cubemap, 0, sky_intensity);
} }
void skybox_sh_reset(skybox_t *sky) { void skybox_sh_reset(skybox_t *sky) {
@ -19203,6 +19216,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
} }
void skybox_destroy(skybox_t *sky) { void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program); glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap); cubemap_destroy(&sky->cubemap);
mesh_destroy(&sky->geometry); mesh_destroy(&sky->geometry);
} }

View File

@ -3293,7 +3293,7 @@ API void cubemap_destroy(cubemap_t *c);
API cubemap_t* cubemap_get_active(); API cubemap_t* cubemap_get_active();
API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height); API void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height);
API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */); API bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */);
API void cubemap_bake_end(cubemap_t *c, float sky_intensity); API void cubemap_bake_end(cubemap_t *c, int step /* = 16 */, float sky_intensity /* = 1.0f */);
API void cubemap_sh_reset(cubemap_t *c); API void cubemap_sh_reset(cubemap_t *c);
API void cubemap_sh_shader(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); API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength);