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.
This commit is contained in:
parent
636a690eb1
commit
032c741214
|
@ -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]),
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in New Issue