Studio Lights: Big Cleanups

* Less Lengthy enum/macro names.
* Optimize computation of Spherical Harmonics.
* Reduce radiance cubemap size a bit. Higher resolution is not necessary.
* Remove STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED (was not used).
* Do windowing on each component separately instead of using luminance.
* Use ITER_PIXELS to iterate on each pixels, using pixel center coords.
* Remove gpu_matcap_3components as it is only needed when creating the gputex.
* Fix a lot of confusion in axis denomination/swizzle.

These changes should not affect functionallity.
This commit is contained in:
Clément Foucault 2018-11-19 01:01:43 +01:00
parent 8d51e3c062
commit ee44dd1b2b
11 changed files with 485 additions and 587 deletions

View File

@ -61,43 +61,36 @@
#define STUDIOLIGHT_ICON_SIZE 96
#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 2
#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 18
/* Only 1 - 5 is supported */
#define STUDIOLIGHT_SH_BANDS 3
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 0
# define STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS 1
#define STUDIOLIGHT_SH_COEFS_LEN (STUDIOLIGHT_SH_BANDS * STUDIOLIGHT_SH_BANDS)
#if STUDIOLIGHT_SH_BANDS > 3
/* Bypass L3 */
#define STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN (STUDIOLIGHT_SH_COEFS_LEN - 7)
#else
#define STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN STUDIOLIGHT_SH_COEFS_LEN
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 1
# define STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS 4
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 2
# define STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS 9
# define STUDIOLIGHT_SPHERICAL_HARMONICS_WINDOWING_TARGET_LAMPLACIAN 10.0f
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 4
# define STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS 18
#endif
struct GPUTexture;
struct StudioLight;
/* StudioLight.flag */
enum StudioLightFlag {
STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED = (1 << 0),
STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1),
/* STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1), */
STUDIOLIGHT_INTERNAL = (1 << 2),
STUDIOLIGHT_EXTERNAL_FILE = (1 << 3),
STUDIOLIGHT_USER_DEFINED = (1 << 12),
STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 4),
STUDIOLIGHT_ORIENTATION_WORLD = (1 << 5),
STUDIOLIGHT_ORIENTATION_VIEWNORMAL = (1 << 6),
STUDIOLIGHT_EXTERNAL_IMAGE_LOADED = (1 << 7),
STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED = (1 << 8),
STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE = (1 << 9),
STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10),
STUDIOLIGHT_EQUIRECT_IRRADIANCE_IMAGE_CALCULATED = (1 << 8),
STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE = (1 << 9),
STUDIOLIGHT_EQUIRECT_IRRADIANCE_GPUTEXTURE = (1 << 10),
STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11),
STUDIOLIGHT_USER_DEFINED = (1 << 12),
STUDIOLIGHT_UI_EXPANDED = (1 << 13),
};
@ -121,14 +114,13 @@ typedef struct StudioLight {
int icon_id_radiance;
int icon_id_matcap;
int icon_id_matcap_flipped;
float spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS][3];
float spherical_harmonics_coefs[STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN][3];
float light_direction[3];
ImBuf *equirectangular_radiance_buffer;
ImBuf *equirectangular_irradiance_buffer;
ImBuf *equirect_radiance_buffer;
ImBuf *equirect_irradiance_buffer;
ImBuf *radiance_cubemap_buffers[6];
struct GPUTexture *equirectangular_radiance_gputexture;
struct GPUTexture *equirectangular_irradiance_gputexture;
float *gpu_matcap_3components; /* 3 channel buffer for GPU_R11F_G11F_B10F */
struct GPUTexture *equirect_radiance_gputexture;
struct GPUTexture *equirect_irradiance_gputexture;
/*
* Free function to clean up the running icons previews (wmJob) the usage is in

File diff suppressed because it is too large Load Diff

View File

@ -123,12 +123,13 @@ 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;
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_IRRADIANCE_GPUTEXTURE);
tex = sl->equirect_irradiance_gputexture;
}
else {
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
tex = sl->equirectangular_radiance_gputexture;
DRW_shgroup_uniform_float_copy(*grp, "studioLightBackground", 1.0f);
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
tex = sl->equirect_radiance_gputexture;
}
DRW_shgroup_uniform_texture(*grp, "image", tex);

View File

@ -4,7 +4,7 @@ struct LightData {
};
struct WorldData {
vec3 spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS];
vec3 spherical_harmonics_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS];
vec4 background_color_low;
vec4 background_color_high;
vec4 object_outline_color;

View File

@ -1,59 +1,52 @@
#define BLINN
vec3 spherical_harmonics(vec3 N, vec3 spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS])
vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
{
vec3 sh = vec3(0.0);
vec3 sh = 0.282095 * sh_coefs[0];
sh += 0.282095 * spherical_harmonics_coefs[0];
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 0
#if STUDIOLIGHT_SH_BANDS > 1
float nx = N.x;
float ny = N.y;
float nz = N.z;
sh += -0.488603 * nz * spherical_harmonics_coefs[1];
sh += 0.488603 * ny * spherical_harmonics_coefs[2];
sh += -0.488603 * nx * spherical_harmonics_coefs[3];
sh += -0.488603 * nz * sh_coefs[1];
sh += 0.488603 * ny * sh_coefs[2];
sh += -0.488603 * nx * sh_coefs[3];
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 1
#if STUDIOLIGHT_SH_BANDS > 2
float nx2 = nx * nx;
float ny2 = ny * ny;
float nz2 = nz * nz;
sh += 1.092548 * nx * nz * spherical_harmonics_coefs[4];
sh += -1.092548 * nz * ny * spherical_harmonics_coefs[5];
sh += 0.315392 * (3.0 * ny2 - 1.0) * spherical_harmonics_coefs[6];
sh += -1.092548 * nx * ny * spherical_harmonics_coefs[7];
sh += 0.546274 * (nx2 - nz2) * spherical_harmonics_coefs[8];
sh += 1.092548 * nx * nz * sh_coefs[4];
sh += -1.092548 * nz * ny * sh_coefs[5];
sh += 0.315392 * (3.0 * ny2 - 1.0) * sh_coefs[6];
sh += -1.092548 * nx * ny * sh_coefs[7];
sh += 0.546274 * (nx2 - nz2) * sh_coefs[8];
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 3
#if STUDIOLIGHT_SH_BANDS > 4
float nx4 = nx2 * nx2;
float ny4 = ny2 * ny2;
float nz4 = nz2 * nz2;
sh += (2.5033429417967046 * nx * nz * (nx2 - nz2)) * spherical_harmonics_coefs[9];
sh += (-1.7701307697799304 * nz * ny * (3.0 * nx2 - nz2)) * spherical_harmonics_coefs[10];
sh += (0.9461746957575601 * nz * nx * (-1.0 +7.0*ny2)) * spherical_harmonics_coefs[11];
sh += (-0.6690465435572892 * nz * ny * (-3.0 + 7.0 * ny2)) * spherical_harmonics_coefs[12];
sh += ((105.0*ny4-90.0*ny2+9.0)/28.359261614) * spherical_harmonics_coefs[13];
sh += (-0.6690465435572892 * nx * ny * (-3.0 + 7.0 * ny2)) * spherical_harmonics_coefs[14];
sh += (0.9461746957575601 * (nx2 - nz2) * (-1.0 + 7.0 * ny2)) * spherical_harmonics_coefs[15];
sh += (-1.7701307697799304 * nx * ny * (nx2 - 3.0 * nz2)) * spherical_harmonics_coefs[16];
sh += (0.6258357354491761 * (nx4 - 6.0 * nz2 * nx2 + nz4)) * spherical_harmonics_coefs[17];
sh += (2.5033429417967046 * nx * nz * (nx2 - nz2)) * sh_coefs[9];
sh += (-1.7701307697799304 * nz * ny * (3.0 * nx2 - nz2)) * sh_coefs[10];
sh += (0.9461746957575601 * nz * nx * (-1.0 +7.0*ny2)) * sh_coefs[11];
sh += (-0.6690465435572892 * nz * ny * (-3.0 + 7.0 * ny2)) * sh_coefs[12];
sh += ((105.0*ny4-90.0*ny2+9.0)/28.359261614) * sh_coefs[13];
sh += (-0.6690465435572892 * nx * ny * (-3.0 + 7.0 * ny2)) * sh_coefs[14];
sh += (0.9461746957575601 * (nx2 - nz2) * (-1.0 + 7.0 * ny2)) * sh_coefs[15];
sh += (-1.7701307697799304 * nx * ny * (nx2 - 3.0 * nz2)) * sh_coefs[16];
sh += (0.6258357354491761 * (nx4 - 6.0 * nz2 * nx2 + nz4)) * sh_coefs[17];
#endif
return sh;
}
vec3 get_world_diffuse_light(WorldData world_data, vec3 N)
{
return (spherical_harmonics(vec3(N.x, N.y, -N.z), world_data.spherical_harmonics_coefs));
return spherical_harmonics(N, world_data.spherical_harmonics_coefs);
}
vec3 get_camera_diffuse_light(WorldData world_data, vec3 N)
{
return (spherical_harmonics(vec3(N.x, -N.z, -N.y), world_data.spherical_harmonics_coefs));
return spherical_harmonics(vec3(N.x, -N.z, N.y), world_data.spherical_harmonics_coefs);
}
/* N And I are in View Space. */

View File

@ -510,8 +510,8 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture);
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
}
workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);

View File

@ -169,8 +169,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
workbench_material_copy(material, &material_template);
if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture);
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
@ -456,8 +456,8 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
float hair_alpha = XRAY_ALPHA(wpd) * 0.33f;
DRW_shgroup_uniform_float_copy(shgrp, "alpha", hair_alpha);
if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(shgrp, "matcapImage", wpd->studio_light->equirectangular_radiance_gputexture);
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(shgrp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
DRW_shgroup_uniform_vec2(shgrp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);

View File

@ -91,19 +91,8 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
}
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 0
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 0\n");
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 1
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 1\n");
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 2
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 2\n");
#endif
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 4
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 4\n");
#endif
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 18\n");
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SH_BANDS %d\n", STUDIOLIGHT_SH_BANDS);
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SH_MAX_COMPONENTS %d\n", STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN);
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);

View File

@ -139,7 +139,7 @@ typedef struct WORKBENCH_UBO_Light {
} WORKBENCH_UBO_Light;
typedef struct WORKBENCH_UBO_World {
float spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS][4];
float spherical_harmonics_coefs[STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN][4];
float background_color_low[4];
float background_color_high[4];
float object_outline_color[4];

View File

@ -34,15 +34,12 @@
void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd)
{
int i;
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED);
for (i = 0; i < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; i++) {
for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) {
/* Can't memcpy because of alignment */
copy_v3_v3(wd->spherical_harmonics_coefs[i], sl->spherical_harmonics_coefs[i]);
}
for (; i < STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS; i++) {
copy_v3_fl(wd->spherical_harmonics_coefs[i], 0.0);
}
}
static void compute_parallel_lines_nor_and_dist(const float v1[2], const float v2[2], const float v3[2], float r_line[2])

View File

@ -726,7 +726,7 @@ static void rna_UserDef_studiolight_spherical_harmonics_coefficients_get(Pointer
{
StudioLight *sl = (StudioLight *)ptr->data;
float *value = values;
for (int i = 0; i < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; i++) {
for (int i = 0; i < STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN; i++) {
copy_v3_v3(value, sl->spherical_harmonics_coefs[i]);
value += 3;
}
@ -3379,7 +3379,7 @@ static void rna_def_userdef_studiolight(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "SH Cache Path", "Path where the spherical harmonics cache is stored");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
const int spherical_harmonics_dim[] = {STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS, 3};
const int spherical_harmonics_dim[] = {STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN, 3};
prop = RNA_def_property(srna, "spherical_harmonics_coefficients", PROP_FLOAT, PROP_COLOR);
RNA_def_property_multi_array(prop, 2, spherical_harmonics_dim);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);