[Bf-blender-cvs] [032c741214b] blender2.8: Studiolight: Calculation of irradiance buffer

Jeroen Bakker noreply at git.blender.org
Thu Jun 21 09:02:50 CEST 2018


Commit: 032c741214b3db579f60941855711b482ed5794e
Author: Jeroen Bakker
Date:   Thu Jun 21 08:56:54 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB032c741214b3db579f60941855711b482ed5794e

Studiolight: Calculation of irradiance buffer

The calculation of the irradiance buffer was slow. Now it is only
calculated when it is being used (background_alpha > 0.0)
this solves the freeze when switching to LookDev mode.

Also changed the default calculation to use the Spherical Harmonics
calculation. This is able to generate the irradiance buffer fast, but is
less accurate. As the irradiance buffer is only used for visual
guidance speed is more important than accuracy.

Added compile directive to switch between the implementations.
(see STUDIOLIGHT_IRRADIANCE_METHOD)

Disabled caching the irradiance buffer when
STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS is used as it is not
needed.

===================================================================

M	source/blender/blenkernel/intern/studiolight.c
M	source/blender/draw/engines/eevee/eevee_lookdev.c

===================================================================

diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 62361917f2f..32cbdc72291 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -60,6 +60,20 @@ static ListBase studiolights;
 #define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT 32
 #define STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH (STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * 2)
 
+#define STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE 0
+#define STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS 1
+/*
+	The method to calculate the irradiance buffers
+	The irradiance buffer is only shown in the background when in LookDev.
+
+	STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE is very slow, but very accurate
+	STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS is faster but has artifacts
+*/
+// #define STUDIOLIGHT_IRRADIANCE_METHOD STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE
+#define STUDIOLIGHT_IRRADIANCE_METHOD STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS
+
+
+
 /*
 	Disable this option so caches are not loaded from disk
 	Do not checkin with this commented out
@@ -471,6 +485,27 @@ static void studiolight_calculate_spherical_harmonics_coefficient(StudioLight *s
 	copy_v3_v3(sl->spherical_harmonics_coefs[sh_component], sh);
 }
 
+BLI_INLINE void studiolight_sample_spherical_harmonics(StudioLight *sl, float color[3], float normal[3])
+{
+	copy_v3_fl(color, 0.0f);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[0], 0.282095f);
+
+#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 0
+	/* Spherical Harmonics L1 */
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[1], -0.488603f * normal[2]);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[2],  0.488603f * normal[1]);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[3], -0.488603f * normal[0]);
+#endif
+
+#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 1
+	/* Spherical Harmonics L1 */
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[4], 1.092548f * normal[0] * normal[2]);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[5], -1.092548f * normal[2] * normal[1]);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[6], 0.315392f * (3.0f * normal[1] * normal[1] - 1.0f));
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[7], -1.092548 * normal[0] * normal[1]);
+	madd_v3_v3fl(color, sl->spherical_harmonics_coefs[8], 0.546274 * (normal[0] * normal[0] - normal[2] * normal[2]));
+#endif
+}
 
 static void studiolight_calculate_diffuse_light(StudioLight *sl)
 {
@@ -608,9 +643,12 @@ static bool studiolight_load_spherical_harmonics_coefficients(StudioLight *sl)
 static void studiolight_calculate_irradiance_equirectangular_image(StudioLight *sl)
 {
 	if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
-		/* check for cached irr file */
-
+#if STUDIOLIGHT_IRRADIANCE_METHOD == STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE
 		BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED);
+#endif
+#if STUDIOLIGHT_IRRADIANCE_METHOD == STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS
+		BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED);
+#endif
 
 		float *colbuf = MEM_mallocN(STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH * STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT * sizeof(float[4]), __func__);
 		float *color = colbuf;
@@ -621,20 +659,33 @@ static void studiolight_calculate_irradiance_equirectangular_image(StudioLight *
 				float xf = x / (float)STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH;
 				float dir[3];
 				equirectangular_to_direction(dir, xf, yf);
+
+#if STUDIOLIGHT_IRRADIANCE_METHOD == STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE
 				studiolight_calculate_specular_irradiance(sl, color, dir);
+#endif
+#if STUDIOLIGHT_IRRADIANCE_METHOD == STUDIOLIGHT_IRRADIANCE_METHOD_SPHERICAL_HARMONICS
+				studiolight_sample_spherical_harmonics(sl, color, dir);
+#endif
+
 				color[3] = 1.0f;
 				color += 4;
 			}
 		}
+
 		sl->equirectangular_irradiance_buffer = IMB_allocFromBuffer(
 		        NULL, colbuf,
 		        STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_WIDTH,
 		        STUDIOLIGHT_IRRADIANCE_EQUIRECTANGULAR_HEIGHT);
 		MEM_freeN(colbuf);
 
+#if STUDIOLIGHT_IRRADIANCE_METHOD == STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE
+		/*
+			Only store cached files when using STUDIOLIGHT_IRRADIANCE_METHOD_RADIANCE
+		*/
 		if (sl->flag & STUDIOLIGHT_USER_DEFINED) {
 			IMB_saveiff(sl->equirectangular_irradiance_buffer, sl->path_irr_cache, IB_rectfloat);
 		}
+#endif
 	}
 	sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED;
 }
@@ -846,25 +897,8 @@ static void studiolight_irradiance_preview(uint* icon_buffer, StudioLight *sl)
 				normal[2] = -sqrtf(1.0f - SQUARE(dist));
 				SWAP(float, normal[1], normal[2]);
 
-				float color[3] = {0.0f, 0.0f, 0.0f};
-				/* Spherical Harmonics L0 */
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[0], 0.282095f);
-
-#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 0
-				/* Spherical Harmonics L1 */
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[1], -0.488603f * normal[2]);
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[2],  0.488603f * normal[1]);
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[3], -0.488603f * normal[0]);
-#endif
-
-#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 1
-				/* Spherical Harmonics L1 */
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[4], 1.092548f * normal[0] * normal[2]);
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[5], -1.092548f * normal[2] * normal[1]);
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[6], 0.315392f * (3.0f * normal[1] * normal[1] - 1.0f));
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[7], -1.092548 * normal[0] * normal[1]);
-				madd_v3_v3fl(color, sl->spherical_harmonics_coefs[8], 0.546274 * (normal[0] * normal[0] - normal[2] * normal[2]));
-#endif
+				float color[3];
+				studiolight_sample_spherical_harmonics(sl, color, normal);
 				pixelresult = rgb_to_cpack(
 				        linearrgb_to_srgb(color[0]),
 				        linearrgb_to_srgb(color[1]),
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 806fb65b8e8..e083c9b5eb5 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -45,7 +45,7 @@ void EEVEE_lookdev_cache_init(
 		StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD);
 		if ((sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) {
 			struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
-			GPUTexture *tex;
+			GPUTexture *tex = NULL;
 
 			*grp = DRW_shgroup_create(shader, pass);
 			axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
@@ -59,15 +59,18 @@ void EEVEE_lookdev_cache_init(
 			if (!pinfo) {
 				/* Do not fadeout when doing probe rendering, only when drawing the background */
 				DRW_shgroup_uniform_float(*grp, "studioLightBackground", &v3d->shading.studiolight_background, 1);
-
-				BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE);
-				tex = sl->equirectangular_irradiance_gputexture;
+				if (v3d->shading.studiolight_background > 0.0f) {
+					BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE);
+					tex = sl->equirectangular_irradiance_gputexture;
+				}
 			}
 			else {
 				BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
 				tex = sl->equirectangular_radiance_gputexture;
 			}
-			DRW_shgroup_uniform_texture(*grp, "image", tex);
+			if (tex != NULL) {
+				DRW_shgroup_uniform_texture(*grp, "image", tex);
+			}
 
 			/* Do we need to recalc the lightprobes? */
 			if (pinfo &&



More information about the Bf-blender-cvs mailing list