summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-01-19 12:39:36 +0100
committerGitHub <noreply@github.com>2020-01-19 12:39:36 +0100
commit4d052e51a203e013cc6572bba4b05661e78d270b (patch)
tree7ba83d7b41147d2b4dd734b5f1fbd0fbff4ef98c
parente8dc581bfca91ddbd87f534aa29a72231dd8581b (diff)
parent0979411cad1a07259cee5f62e1d2e77bd3ac6c62 (diff)
Merge pull request #35302 from clayjohn/GLES3-env-map
Reduce complexity of irradiance map generation
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp43
-rw-r--r--drivers/gles3/shaders/copy.glsl8
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl4
3 files changed, 51 insertions, 4 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 801763609e..26fbdfc73d 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -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
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index 1952e201aa..a3cdb3a543 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -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
@@ -190,8 +194,12 @@ void main() {
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
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 3f3313c3a7..15d4e2d58e 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -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