瀏覽代碼

Merge pull request #35561 from clayjohn/GLES3-irradiance-max

Add project setting for max irradiance size
Rémi Verschelde 5 年之前
父節點
當前提交
1b3eb41622
共有 3 個文件被更改,包括 12 次插入4 次删除
  1. 4 0
      doc/classes/ProjectSettings.xml
  2. 6 4
      drivers/gles3/rasterizer_storage_gles3.cpp
  3. 2 0
      servers/visual_server.cpp

+ 4 - 0
doc/classes/ProjectSettings.xml

@@ -901,6 +901,10 @@
 		</member>
 		</member>
 		<member name="rendering/quality/reflections/high_quality_ggx.mobile" type="bool" setter="" getter="" default="false">
 		<member name="rendering/quality/reflections/high_quality_ggx.mobile" type="bool" setter="" getter="" default="false">
 		</member>
 		</member>
+		<member name="rendering/quality/reflections/irradiance_max_size" type="int" setter="" getter="" default="128">
+			Limits the size of the irradiance map which is normally determined by [member Sky.radiance_size]. A higher size results in a higher quality irradiance map similarly to [member rendering/quality/reflections/high_quality_ggx]. Use a higher value when using high-frequency HDRI maps, otherwise keep this as low as possible.
+			[b]Note:[/b] Low and mid range hardware do not support complex irradiance maps well and may crash if this is set too high.
+		</member>
 		<member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true">
 		<member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true">
 			If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise on reflections, but costs more performance and memory.
 			If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise on reflections, but costs more performance and memory.
 		</member>
 		</member>

+ 6 - 4
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -1854,6 +1854,9 @@ 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);
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->irradiance, 0);
 
 
+		int irradiance_size = GLOBAL_GET("rendering/quality/reflections/irradiance_max_size");
+		int upscale_size = MIN(int(previous_power_of_2(irradiance_size)), p_radiance_size);
+
 		GLuint tmp_fb2;
 		GLuint tmp_fb2;
 		GLuint tmp_tex;
 		GLuint tmp_tex;
 		{
 		{
@@ -1862,7 +1865,7 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
 			glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
 			glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
 			glGenTextures(1, &tmp_tex);
 			glGenTextures(1, &tmp_tex);
 			glBindTexture(GL_TEXTURE_2D, 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);
+			glTexImage2D(GL_TEXTURE_2D, 0, internal_format, upscale_size, 2.0 * upscale_size, 0, format, type, NULL);
 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
 			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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -1882,9 +1885,8 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
 		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));
 		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
 		// 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++) {
 		for (int i = 0; i < 2; i++) {
-			glViewport(0, i * vp_size, vp_size, vp_size);
+			glViewport(0, i * upscale_size, upscale_size, upscale_size);
 			glBindVertexArray(resources.quadie_array);
 			glBindVertexArray(resources.quadie_array);
 
 
 			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
 			shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
@@ -1903,7 +1905,7 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
 
 
 		shaders.copy.set_conditional(CopyShaderGLES3::USE_LOD, true);
 		shaders.copy.set_conditional(CopyShaderGLES3::USE_LOD, true);
 		shaders.copy.bind();
 		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
+		shaders.copy.set_uniform(CopyShaderGLES3::MIP_LEVEL, MAX(Math::floor(Math::log(float(upscale_size)) / Math::log(2.0f)) - 5.0f, 0.0f)); // Mip level that corresponds to a 32x32 texture
 
 
 		glViewport(0, 0, size, size * 2.0);
 		glViewport(0, 0, size, size * 2.0);
 		glBindVertexArray(resources.quadie_array);
 		glBindVertexArray(resources.quadie_array);

+ 2 - 0
servers/visual_server.cpp

@@ -2397,6 +2397,8 @@ VisualServer::VisualServer() {
 	GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
 	GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
 	GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx", true);
 	GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx", true);
 	GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx.mobile", false);
 	GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx.mobile", false);
+	GLOBAL_DEF("rendering/quality/reflections/irradiance_max_size", 128);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/irradiance_max_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/irradiance_max_size", PROPERTY_HINT_RANGE, "32,2048"));
 
 
 	GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
 	GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
 	GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
 	GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);