reduce complexity of irradiance map generation

This commit is contained in:
clayjohn 2020-01-18 16:38:20 -08:00
parent d4a222cd9d
commit 0979411cad
3 changed files with 51 additions and 4 deletions

View file

@ -1834,7 +1834,7 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glGenFramebuffers(1, &tmp_fb);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
int size = 64;
int size = 32;
bool use_float = config.framebuffer_half_float_supported;
@ -1854,6 +1854,24 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->irradiance, 0);
GLuint tmp_fb2;
GLuint tmp_tex;
{
//generate another one for rendering, as can't read and write from a single texarray it seems
glGenFramebuffers(1, &tmp_fb2);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
glGenTextures(1, &tmp_tex);
glBindTexture(GL_TEXTURE_2D, tmp_tex);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, p_radiance_size, 2.0 * p_radiance_size, 0, format, type, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
#ifdef DEBUG_ENABLED
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
#endif
}
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::COMPUTE_IRRADIANCE, true);
@ -1863,8 +1881,10 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
// level that corresponds to a panorama of 1024x512
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_MIP_LEVEL, MAX(Math::floor(Math::log(float(texture->width)) / Math::log(2.0f)) - 10.0f, 0.0f));
// Compute Irradiance for a large texture, specified by radiance size and then pull out a low mipmap corresponding to 32x32
int vp_size = p_radiance_size;
for (int i = 0; i < 2; i++) {
glViewport(0, i * size, size, size);
glViewport(0, i * vp_size, vp_size, vp_size);
glBindVertexArray(resources.quadie_array);
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
@ -1872,13 +1892,32 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
}
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tmp_tex);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::COMPUTE_IRRADIANCE, false);
shaders.copy.set_conditional(CopyShaderGLES3::USE_LOD, true);
shaders.copy.bind();
shaders.copy.set_uniform(CopyShaderGLES3::MIP_LEVEL, MAX(Math::floor(Math::log(float(p_radiance_size)) / Math::log(2.0f)) - 5.0f, 0.0f)); // Mip level that corresponds to a 32x32 texture
glViewport(0, 0, size, size * 2.0);
glBindVertexArray(resources.quadie_array);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
shaders.copy.set_conditional(CopyShaderGLES3::USE_LOD, false);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
glDeleteFramebuffers(1, &tmp_fb);
glDeleteFramebuffers(1, &tmp_fb2);
glDeleteTextures(1, &tmp_tex);
}
// Now compute radiance

View file

@ -104,6 +104,10 @@ uniform sampler2D CbCr; //texunit:1
/* clang-format on */
#ifdef USE_LOD
uniform float mip_level;
#endif
#if defined(USE_TEXTURE3D) || defined(USE_TEXTURE2DARRAY)
uniform float layer;
#endif
@ -189,9 +193,13 @@ void main() {
color.r = textureLod(source, uv_interp, 0.0).r;
color.gb = textureLod(CbCr, uv_interp, 0.0).rg - vec2(0.5, 0.5);
color.a = 1.0;
#else
#ifdef USE_LOD
vec4 color = textureLod(source, uv_interp, mip_level);
#else
vec4 color = textureLod(source, uv_interp, 0.0);
#endif
#endif
#ifdef LINEAR_TO_SRGB
// regular Linear -> SRGB conversion

View file

@ -183,12 +183,12 @@ vec2 Hammersley(uint i, uint N) {
#ifdef LOW_QUALITY
#define SAMPLE_COUNT 64u
#define SAMPLE_DELTA 0.05
#define SAMPLE_DELTA 0.1
#else
#define SAMPLE_COUNT 512u
#define SAMPLE_DELTA 0.01
#define SAMPLE_DELTA 0.03
#endif