Studiolight: Spherical harmonics
Compile time option to reduce the level of the SH
This commit is contained in:
@@ -61,6 +61,22 @@
|
||||
|
||||
#define STUDIOLIGHT_ICON_SIZE 96
|
||||
|
||||
#define STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL 2
|
||||
#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 9
|
||||
|
||||
|
||||
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL == 0
|
||||
#define STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS 1
|
||||
#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
|
||||
#endif
|
||||
|
||||
struct GPUTexture;
|
||||
struct StudioLight;
|
||||
|
||||
@@ -97,12 +113,12 @@ typedef struct StudioLight {
|
||||
char name[FILE_MAXFILE];
|
||||
char path[FILE_MAX];
|
||||
char *path_irr_cache;
|
||||
char *path_sh2_cache;
|
||||
char *path_sh_cache;
|
||||
int icon_id_irradiance;
|
||||
int icon_id_radiance;
|
||||
int icon_id_matcap;
|
||||
int icon_id_matcap_flipped;
|
||||
float spherical_harmonics_coefs[9][3];
|
||||
float spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS][3];
|
||||
float light_direction[3];
|
||||
ImBuf *equirectangular_radiance_buffer;
|
||||
ImBuf *equirectangular_irradiance_buffer;
|
||||
|
||||
@@ -110,7 +110,7 @@ static void studiolight_free(struct StudioLight *sl)
|
||||
IMB_SAFE_FREE(sl->equirectangular_radiance_buffer);
|
||||
IMB_SAFE_FREE(sl->equirectangular_irradiance_buffer);
|
||||
MEM_SAFE_FREE(sl->path_irr_cache);
|
||||
MEM_SAFE_FREE(sl->path_sh2_cache);
|
||||
MEM_SAFE_FREE(sl->path_sh_cache);
|
||||
MEM_SAFE_FREE(sl->gpu_matcap_3components);
|
||||
MEM_SAFE_FREE(sl);
|
||||
}
|
||||
@@ -121,7 +121,7 @@ static struct StudioLight *studiolight_create(int flag)
|
||||
sl->path[0] = 0x00;
|
||||
sl->name[0] = 0x00;
|
||||
sl->path_irr_cache = NULL;
|
||||
sl->path_sh2_cache = NULL;
|
||||
sl->path_sh_cache = NULL;
|
||||
sl->free_function = NULL;
|
||||
sl->flag = flag;
|
||||
sl->index = BLI_listbase_count(&studiolights);
|
||||
@@ -478,14 +478,11 @@ static void studiolight_calculate_diffuse_light(StudioLight *sl)
|
||||
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED);
|
||||
|
||||
for (int comp = 0; comp < 9; comp ++) {
|
||||
for (int comp = 0; comp < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; comp ++) {
|
||||
studiolight_calculate_spherical_harmonics_coefficient(sl, comp);
|
||||
#if 0
|
||||
print_v3("SH2", sl->spherical_harmonics_coefs[comp]);
|
||||
#endif
|
||||
}
|
||||
if (sl->flag & STUDIOLIGHT_USER_DEFINED) {
|
||||
FILE *fp = BLI_fopen(sl->path_sh2_cache, "wb");
|
||||
FILE *fp = BLI_fopen(sl->path_sh_cache, "wb");
|
||||
if (fp) {
|
||||
fwrite(sl->spherical_harmonics_coefs, sizeof(sl->spherical_harmonics_coefs), 1, fp);
|
||||
fclose(fp);
|
||||
@@ -593,7 +590,7 @@ static bool studiolight_load_spherical_harmonics_coefficients(StudioLight *sl)
|
||||
{
|
||||
#ifdef STUDIOLIGHT_LOAD_CACHED_FILES
|
||||
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
|
||||
FILE *fp = BLI_fopen(sl->path_sh2_cache, "rb");
|
||||
FILE *fp = BLI_fopen(sl->path_sh_cache, "rb");
|
||||
if (fp) {
|
||||
if (fread((void*)(sl->spherical_harmonics_coefs), sizeof(sl->spherical_harmonics_coefs), 1, fp))
|
||||
{
|
||||
@@ -693,7 +690,7 @@ static void studiolight_add_files_from_datafolder(const int folder_id, const cha
|
||||
BLI_strncpy(sl->name, filename, FILE_MAXFILE);
|
||||
BLI_strncpy(sl->path, path, FILE_MAXFILE);
|
||||
sl->path_irr_cache = BLI_string_joinN(path, ".irr");
|
||||
sl->path_sh2_cache = BLI_string_joinN(path, ".sh2");
|
||||
sl->path_sh_cache = BLI_string_joinN(path, ".sh2");
|
||||
BLI_addtail(&studiolights, sl);
|
||||
}
|
||||
}
|
||||
@@ -853,17 +850,21 @@ static void studiolight_irradiance_preview(uint* icon_buffer, StudioLight *sl)
|
||||
/* 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
|
||||
pixelresult = rgb_to_cpack(
|
||||
linearrgb_to_srgb(color[0]),
|
||||
linearrgb_to_srgb(color[1]),
|
||||
@@ -885,15 +886,20 @@ void BKE_studiolight_init(void)
|
||||
sl = studiolight_create(STUDIOLIGHT_INTERNAL | STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
BLI_strncpy(sl->name, "Default", FILE_MAXFILE);
|
||||
|
||||
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[0], 1.03271556f, 1.07163882f, 1.11193657f);
|
||||
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 0
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[1], -0.00480952f, 0.05290511f, 0.16394117f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[2], -0.29686999f, -0.27378261f, -0.24797194f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[3], 0.47932500f, 0.48242140f, 0.47190312f);
|
||||
#endif
|
||||
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 1
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[4], -0.00576984f, 0.00504886f, 0.01640534f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[5], 0.15500379f, 0.15415503f, 0.16244425f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[6], -0.02483751f, -0.02245096f, -0.00536885f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[7], 0.11155496f, 0.11005443f, 0.10839636f);
|
||||
copy_v3_fl3(sl->spherical_harmonics_coefs[8], 0.01363425f, 0.01278363f, -0.00159006f);
|
||||
#endif
|
||||
|
||||
BLI_addtail(&studiolights, sl);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ struct LightData {
|
||||
};
|
||||
|
||||
struct WorldData {
|
||||
vec3 spherical_harmonics_coefs[9];
|
||||
vec3 spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS];
|
||||
vec4 background_color_low;
|
||||
vec4 background_color_high;
|
||||
vec4 object_outline_color;
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
#define BLINN
|
||||
|
||||
vec3 spherical_harmonics_L2(vec3 N, vec3 spherical_harmonics_coefs[9])
|
||||
vec3 spherical_harmonics(vec3 N, vec3 spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS])
|
||||
{
|
||||
vec3 sh = vec3(0.0);
|
||||
|
||||
sh += 0.282095 * spherical_harmonics_coefs[0];
|
||||
|
||||
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 0
|
||||
sh += -0.488603 * N.z * spherical_harmonics_coefs[1];
|
||||
sh += 0.488603 * N.y * spherical_harmonics_coefs[2];
|
||||
sh += -0.488603 * N.x * spherical_harmonics_coefs[3];
|
||||
#endif
|
||||
|
||||
#if STUDIOLIGHT_SPHERICAL_HARMONICS_LEVEL > 1
|
||||
sh += 1.092548 * N.x * N.z * spherical_harmonics_coefs[4];
|
||||
sh += -1.092548 * N.z * N.y * spherical_harmonics_coefs[5];
|
||||
sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * spherical_harmonics_coefs[6];
|
||||
sh += -1.092548 * N.x * N.y * spherical_harmonics_coefs[7];
|
||||
sh += 0.546274 * (N.x * N.x - N.z * N.z) * spherical_harmonics_coefs[8];
|
||||
#endif
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
vec3 get_world_diffuse_light(WorldData world_data, vec3 N)
|
||||
{
|
||||
return (spherical_harmonics_L2(vec3(N.x, N.y, -N.z), world_data.spherical_harmonics_coefs));
|
||||
return (spherical_harmonics(vec3(N.x, N.y, -N.z), world_data.spherical_harmonics_coefs));
|
||||
}
|
||||
|
||||
vec3 get_camera_diffuse_light(WorldData world_data, vec3 N)
|
||||
{
|
||||
return (spherical_harmonics_L2(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. */
|
||||
|
||||
@@ -95,6 +95,17 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype,
|
||||
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
|
||||
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS 9\n");
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
return str;
|
||||
|
||||
@@ -112,7 +112,7 @@ typedef struct WORKBENCH_UBO_Light {
|
||||
} WORKBENCH_UBO_Light;
|
||||
|
||||
typedef struct WORKBENCH_UBO_World {
|
||||
float spherical_harmonics_coefs[9][4];
|
||||
float spherical_harmonics_coefs[STUDIOLIGHT_SPHERICAL_HARMONICS_MAX_COMPONENTS][4];
|
||||
float background_color_low[4];
|
||||
float background_color_high[4];
|
||||
float object_outline_color[4];
|
||||
|
||||
@@ -34,10 +34,15 @@
|
||||
|
||||
void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd)
|
||||
{
|
||||
int i;
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
|
||||
for (i = 0; i < STUDIOLIGHT_SPHERICAL_HARMONICS_COMPONENTS; i++) {
|
||||
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])
|
||||
|
||||
Reference in New Issue
Block a user