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();
void cubemap_bake_begin(cubemap_t *c, vec3 pos, unsigned width, unsigned height);
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_shader(cubemap_t *c);
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) {
probe_pos = cam.position;
}
unsigned tex_size = 256;
unsigned tex_size = 128;
cubemap_bake_begin(&env_probe.cubemap, probe_pos, tex_size, tex_size);
while (cubemap_bake_step(&env_probe.cubemap, 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);
}
cubemap_bake_end(&env_probe.cubemap, 1.2f);
cubemap_bake_end(&env_probe.cubemap, 8, 1.0f);
}
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 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 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_shader(cubemap_t *c);
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->height = height;
if (!c->framebuffers[0]) {
if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers);
@ -383686,24 +383686,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
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 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]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1);
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);
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;
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) {
sky_intensity = 1.0f;
}
if (!step) {
step = 16;
}
if (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);
#else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0;
for (int i = 0; i < 6; 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
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 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16;
// const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
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) {
float *p = (float*)(c->pixels + y * c->width * 3);
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);
}
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
// Copy each face of the cubemap to the cubemap texture
// 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);
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)) {
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) {
@ -384088,6 +384101,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
}
void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap);
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->height = height;
if (!c->framebuffers[0]) {
if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers);
@ -2002,24 +2002,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
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 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]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1);
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);
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;
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) {
sky_intensity = 1.0f;
}
if (!step) {
step = 16;
}
if (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);
#else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0;
for (int i = 0; i < 6; 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
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 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16;
// const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
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) {
float *p = (float*)(c->pixels + y * c->width * 3);
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);
}
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
// Copy each face of the cubemap to the cubemap texture
// 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);
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)) {
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) {
@ -2404,6 +2417,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
}
void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap);
mesh_destroy(&sky->geometry);
}

View File

@ -258,7 +258,7 @@ API void cubemap_destroy(cubemap_t *c);
API cubemap_t* cubemap_get_active();
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 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_shader(cubemap_t *c);
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->height = height;
if (!c->framebuffers[0]) {
if (c->framebuffers[0]) {
glDeleteFramebuffers(6, c->framebuffers);
glDeleteTextures(6, c->textures);
glDeleteRenderbuffers(6, c->depth_buffers);
@ -18801,24 +18801,29 @@ bool cubemap_bake_step(cubemap_t *c, mat44 proj /* out */, mat44 view /* out */)
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 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]);
glViewport(0, 0, c->width, c->height);
glClearColor(0, 0, 0, 1);
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);
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;
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) {
sky_intensity = 1.0f;
}
if (!step) {
step = 16;
}
if (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);
#else
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
int samples = 0;
for (int i = 0; i < 6; 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
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 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
int step = 16;
// const vec3 skyY[] = {{ 0, 1, 0},{ 0, 1, 0},{ 0, 0,-1},{ 0, 0, 1},{ 0, 1, 0},{ 0, 1, 0}};
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) {
float *p = (float*)(c->pixels + y * c->width * 3);
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);
}
glGenTextures(1, &c->id);
glBindTexture(GL_TEXTURE_CUBE_MAP, c->id);
// Copy each face of the cubemap to the cubemap texture
// 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);
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)) {
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) {
@ -19203,6 +19216,7 @@ int skybox_render(skybox_t *sky, mat44 proj, mat44 view) {
}
void skybox_destroy(skybox_t *sky) {
glDeleteProgram(sky->program);
glDeleteProgram(sky->rayleigh_program);
cubemap_destroy(&sky->cubemap);
mesh_destroy(&sky->geometry);
}

View File

@ -3293,7 +3293,7 @@ API void cubemap_destroy(cubemap_t *c);
API cubemap_t* cubemap_get_active();
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 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_shader(cubemap_t *c);
API void cubemap_sh_add_light(cubemap_t *c, vec3 light, vec3 dir, float strength);