41#define STUDIOLIGHT_PASSNAME_DIFFUSE "diffuse"
42#define STUDIOLIGHT_PASSNAME_SPECULAR "specular"
66#define ITER_PIXELS(type, src, channels, width, height) \
68 float texel_size[2]; \
69 texel_size[0] = 1.0f / width; \
70 texel_size[1] = 1.0f / height; \
71 type(*pixel_)[channels] = (type(*)[channels])src; \
72 for (float y = 0.5 * texel_size[1]; y < 1.0; y += texel_size[1]) { \
73 for (float x = 0.5 * texel_size[0]; x < 1.0; x += texel_size[0], pixel_++) { \
74 type *pixel = *pixel_;
76#define ITER_PIXELS_END \
83#define IMB_SAFE_FREE(p) \
91#define GPU_TEXTURE_SAFE_FREE(p) \
94 GPU_texture_free(p); \
101 sl->
flag &= ~STUDIOLIGHT_EXTERNAL_IMAGE_LOADED;
109#define STUDIOLIGHT_DELETE_ICON(s) \
112 BKE_icon_delete(s); \
124#undef STUDIOLIGHT_DELETE_ICON
144 if (is_used_in_viewport) {
173#define STUDIOLIGHT_FILE_VERSION 1
175#define READ_VAL(type, parser, id, val, lines) \
177 for (LinkNode *line = lines; line; line = line->next) { \
178 char *val_str, *str = static_cast<char *>(line->link); \
179 if ((val_str = strstr(str, id " "))) { \
180 val_str += sizeof(id); \
181 val = parser(val_str); \
186#define READ_FVAL(id, val, lines) READ_VAL(float, atof, id, val, lines)
187#define READ_IVAL(id, val, lines) READ_VAL(int, atoi, id, val, lines)
189#define READ_VEC3(id, val, lines) \
191 READ_FVAL(id ".x", val[0], lines); \
192 READ_FVAL(id ".y", val[1], lines); \
193 READ_FVAL(id ".z", val[2], lines); \
196#define READ_SOLIDLIGHT(sl, i, lines) \
198 READ_IVAL("light[" STRINGIFY(i) "].flag", sl[i].flag, lines); \
199 READ_FVAL("light[" STRINGIFY(i) "].smooth", sl[i].smooth, lines); \
200 READ_VEC3("light[" STRINGIFY(i) "].col", sl[i].col, lines); \
201 READ_VEC3("light[" STRINGIFY(i) "].spec", sl[i].spec, lines); \
202 READ_VEC3("light[" STRINGIFY(i) "].vec", sl[i].vec, lines); \
218#undef READ_SOLIDLIGHT
223#define WRITE_FVAL(str, id, val) BLI_dynstr_appendf(str, id " %f\n", val)
224#define WRITE_IVAL(str, id, val) BLI_dynstr_appendf(str, id " %d\n", val)
226#define WRITE_VEC3(str, id, val) \
228 WRITE_FVAL(str, id ".x", val[0]); \
229 WRITE_FVAL(str, id ".y", val[1]); \
230 WRITE_FVAL(str, id ".z", val[2]); \
233#define WRITE_SOLIDLIGHT(str, sl, i) \
235 WRITE_IVAL(str, "light[" STRINGIFY(i) "].flag", sl[i].flag); \
236 WRITE_FVAL(str, "light[" STRINGIFY(i) "].smooth", sl[i].smooth); \
237 WRITE_VEC3(str, "light[" STRINGIFY(i) "].col", sl[i].col); \
238 WRITE_VEC3(str, "light[" STRINGIFY(i) "].spec", sl[i].spec); \
239 WRITE_VEC3(str, "light[" STRINGIFY(i) "].vec", sl[i].vec); \
266#undef WRITE_SOLIDLIGHT
304 float *new_rect =
static_cast<float *
>(
305 MEM_callocN(
sizeof(
float[4]) * ibuf->
x * ibuf->
y, __func__));
324 const char *pass_name,
351 ImBuf *specular_ibuf =
nullptr;
352 ImBuf *diffuse_ibuf =
nullptr;
353 const bool failed = (ibuf ==
nullptr);
402 if (diffuse_ibuf ==
nullptr) {
405 const float black[4] = {0.0f, 0.0f, 0.0f, 1.0f};
406 const float magenta[4] = {1.0f, 0.0f, 1.0f, 1.0f};
408 nullptr, (failed || (specular_ibuf ==
nullptr)) ? magenta : black, 1, 1, 4);
414 if (specular_ibuf !=
nullptr) {
420 if (specular_ibuf !=
nullptr) {
453 float *gpu_matcap_3components =
static_cast<float *
>(
454 MEM_callocN(
sizeof(
float[3]) * ibuf->
x * ibuf->
y, __func__));
457 float(*offset3)[3] = (
float(*)[3])gpu_matcap_3components;
458 for (
int i = 0; i < ibuf->
x * ibuf->
y; i++, offset4++, offset3++) {
504 return atan2(x * y,
sqrtf(x * x + y * y + 1));
507static float brdf_approx(
float spec_color,
float roughness,
float NV)
511 float fresnel = exp2(-8.35f * NV) * (1.0f - roughness);
512 return spec_color * (1.0f - fresnel) + fresnel;
518 float w_1 =
w + 1.0f;
519 return max_ff((
NL +
w) / (w_1 * w_1), 0.0f);
536 float gloss = 1.0f - roughness;
538 gloss *= 1.0f -
wrap;
539 float shininess = exp2(10.0f * gloss + 1.0f);
543 float normalization_factor = shininess * 0.125f + 1.0f;
544 float spec_light =
powf(spec_angle, shininess) *
max_ff(
NL, 0.0f) * normalization_factor;
547 float w =
wrap * (1.0 - roughness) + roughness;
552 return spec_light * (1.0 - w2) + spec_env * w2;
558 float R[3],
I[3] = {0.0f, 0.0f, 1.0f},
N[3] = {normal[0], normal[2], -normal[1]};
559 const float roughness = 0.5f;
560 const float diffuse_color = 0.8f;
561 const float specular_color =
brdf_approx(0.05f, roughness,
N[2]);
562 float diff_light[3], spec_light[3];
583 mul_v3_fl(diff_light, diffuse_color * (1.0 - specular_color));
611 const char *subfolder,
622 for (i = 0; i < dirs_num; i++) {
623 if (dirs[i].type & S_IFREG) {
648 if (flagorder1 < flagorder2) {
651 if (flagorder1 > flagorder2) {
666 const float co[2] = {u - 0.5f,
v - 0.5f};
668 float alpha = 1.0f + (inner_edge - dist) / (outer_edge - inner_edge);
674#define STUDIOLIGHT_DIAMETER 0.95f
676#define RESCALE_COORD(x) (x / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f)
681 normal[0] = u * 2.0f - 1.0f;
682 normal[1] =
v * 2.0f - 1.0f;
683 float dist =
len_v2(normal);
696 if (alphamask != 0) {
697 float normal[3], direction[3];
698 const float incoming[3] = {0.0f, 0.0f, -1.0f};
702 std::swap(direction[1], direction[2]);
703 direction[1] = -direction[1];
735 float u = dx * diffuse_buffer->
x - 1.0f;
736 float v = dy * diffuse_buffer->
y - 1.0f;
737 float4 color = imbuf::interpolate_nearest_border_fl(diffuse_buffer, u,
v);
739 if (specular_buffer) {
740 float4 specular = imbuf::interpolate_nearest_border_fl(specular_buffer, u,
v);
761 if (alphamask != 0) {
762 float normal[3], color[3];
765 std::swap(normal[1], normal[2]);
766 normal[1] = -normal[1];
787 lights[0].
smooth = 0.526620f;
788 lights[0].
col[0] = 0.033103f;
789 lights[0].
col[1] = 0.033103f;
790 lights[0].
col[2] = 0.033103f;
791 lights[0].
spec[0] = 0.266761f;
792 lights[0].
spec[1] = 0.266761f;
793 lights[0].
spec[2] = 0.266761f;
794 lights[0].
vec[0] = -0.352546f;
795 lights[0].
vec[1] = 0.170931f;
796 lights[0].
vec[2] = -0.920051f;
799 lights[1].
smooth = 0.000000f;
800 lights[1].
col[0] = 0.521083f;
801 lights[1].
col[1] = 0.538226f;
802 lights[1].
col[2] = 0.538226f;
803 lights[1].
spec[0] = 0.599030f;
804 lights[1].
spec[1] = 0.599030f;
805 lights[1].
spec[2] = 0.599030f;
806 lights[1].
vec[0] = -0.408163f;
807 lights[1].
vec[1] = 0.346939f;
808 lights[1].
vec[2] = 0.844415f;
811 lights[2].
smooth = 0.478261f;
812 lights[2].
col[0] = 0.038403f;
813 lights[2].
col[1] = 0.034357f;
814 lights[2].
col[2] = 0.049530f;
815 lights[2].
spec[0] = 0.106102f;
816 lights[2].
spec[1] = 0.125981f;
817 lights[2].
spec[2] = 0.158523f;
818 lights[2].
vec[0] = 0.521739f;
819 lights[2].
vec[1] = 0.826087f;
820 lights[2].
vec[2] = 0.212999f;
823 lights[3].
smooth = 0.200000f;
824 lights[3].
col[0] = 0.090838f;
825 lights[3].
col[1] = 0.082080f;
826 lights[3].
col[2] = 0.072255f;
827 lights[3].
spec[0] = 0.106535f;
828 lights[3].
spec[1] = 0.084771f;
829 lights[3].
spec[2] = 0.066080f;
830 lights[3].
vec[0] = 0.624519f;
831 lights[3].
vec[1] = -0.562067f;
832 lights[3].
vec[2] = -0.542269f;
880 const char *default_name =
"";
890 if ((sl->flag &
flag) &&
STREQ(sl->name, default_name)) {
896 if (sl->flag &
flag) {
907 if (sl->flag &
flag) {
922 if (sl->index == index) {
937 switch (icon_id_type) {
999 const float light_ambient[3])
1010 memcpy(sl->
light, light,
sizeof(*light) * 4);
1011 memcpy(sl->
light_ambient, light_ambient,
sizeof(*light_ambient) * 3);
1024 memcpy(sl.
light,
U.light_param,
sizeof(*sl.
light) * 4);
@ BLENDER_SYSTEM_DATAFILES
std::optional< std::string > BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT
int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP
#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP_FLIPPED
#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE
@ STUDIOLIGHT_EXTERNAL_IMAGE_LOADED
@ STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE
@ STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE
@ STUDIOLIGHT_USER_DEFINED
@ STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE
@ STUDIOLIGHT_TYPE_MATCAP
@ STUDIOLIGHT_SPECULAR_HIGHLIGHT_PASS
@ STUDIOLIGHT_TYPE_STUDIO
@ STUDIOLIGHT_EXTERNAL_FILE
void StudioLightFreeFunction(struct StudioLight *, void *data)
#define STUDIOLIGHT_ICON_SIZE
#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE
#define STUDIOLIGHT_MAX_LIGHT
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
struct LinkNode * BLI_file_read_as_lines(const char *filepath) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_file_free_lines(struct LinkNode *lines)
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
Some types for dealing with directories.
#define LISTBASE_FOREACH(type, var, list)
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float square_f(float a)
unsigned int rgb_to_cpack(float r, float g, float b)
float linearrgb_to_srgb(float c)
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
bool BLI_path_extension_check_array(const char *path, const char **ext_array) ATTR_NONNULL(1
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
bool BLI_path_extension_check(const char *path, const char *ext) ATTR_NONNULL(1
#define STRNCPY(dst, src)
int char char int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STREQLEN(a, b, n)
These structs are the foundation for all linked lists in the library system.
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_extend_mode(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_SAMPLER_EXTEND_MODE_REPEAT
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
ImBuf * IMB_allocFromBufferOwn(uint8_t *byte_buffer, float *float_buffer, unsigned int w, unsigned int h, unsigned int channels)
void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, int channels_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
void IMB_float_from_rect(ImBuf *ibuf)
#define IB_PROFILE_LINEAR_RGB
const char * imb_ext_image[]
void IMB_exr_close(void *handle)
void IMB_exr_multilayer_convert(void *handle, void *base, void *(*addview)(void *base, const char *str), void *(*addlayer)(void *base, const char *str), void(*addpass)(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view))
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
local_group_size(16, 16) .push_constant(Type b
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
draw_view in_light_buf[] float
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
struct ImBuf * IMB_allocFromBuffer(const uint8_t *, const float *, unsigned int, unsigned int, unsigned int)
void IMB_freeImBuf(ImBuf *)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
float4 interpolate_nearest_border_fl(const ImBuf *in, float u, float v)
float wrap(float value, float max, float min)
ImBufFloatBuffer float_buffer
int num_specular_channels
struct GPUTexture * gputexture
StudioLightImage matcap_specular
SolidLight light[STUDIOLIGHT_MAX_LIGHT]
void * free_function_data
struct GPUTexture * equirect_radiance_gputexture
StudioLightFreeFunction * free_function
struct ImBuf * equirect_radiance_buffer
int icon_id_matcap_flipped
StudioLightImage matcap_diffuse
static void studiolight_create_matcap_specular_gputexture(StudioLight *sl)
#define STUDIOLIGHT_FILE_VERSION
static const char * STUDIOLIGHT_LIGHTS_FOLDER
static void * studiolight_multilayer_addlayer(void *base, const char *)
static void studiolight_radiance_preview(uint *icon_buffer, StudioLight *sl)
#define WRITE_IVAL(str, id, val)
void BKE_studiolight_remove(StudioLight *sl)
#define STUDIOLIGHT_PASSNAME_DIFFUSE
static StudioLight * studiolight_add_file(const char *filepath, int flag)
static void studiolight_lights_eval(StudioLight *sl, const float normal[3], float r_color[3])
StudioLight * BKE_studiolight_studio_edit_get()
static float * studiolight_multilayer_convert_pass(const ImBuf *ibuf, float *rect, const uint channels)
static void studiolight_free_temp_resources(StudioLight *sl)
static void studiolight_irradiance_preview(uint *icon_buffer, StudioLight *sl)
static const char * STUDIOLIGHT_MATCAP_DEFAULT
static float4 studiolight_calculate_radiance(const ImBuf *ibuf, const float direction[3])
#define WRITE_SOLIDLIGHT(str, sl, i)
static int last_studiolight_id
static int studiolight_cmp(const void *a, const void *b)
#define ITER_PIXELS(type, src, channels, width, height)
static int studiolight_flag_cmp_order(const StudioLight *sl)
StudioLight * BKE_studiolight_load(const char *filepath, int type)
static StudioLight * studiolight_create(int flag)
static ListBase studiolights
static void studiolight_free(StudioLight *sl)
static void studiolight_load_equirect_image(StudioLight *sl)
void BKE_studiolight_unset_icon_id(StudioLight *sl, int icon_id)
static uint alpha_circle_mask(float u, float v, float inner_edge, float outer_edge)
StudioLight * BKE_studiolight_find_default(int flag)
static void studiolight_multilayer_addpass(void *base, void *, const char *pass_name, float *rect, int num_channels, const char *, const char *)
static void studiolight_create_matcap_gputexture(StudioLightImage *sli)
static void sphere_normal_from_uv(float normal[3], float u, float v)
void BKE_studiolight_set_free_function(StudioLight *sl, StudioLightFreeFunction *free_function, void *data)
StudioLight * BKE_studiolight_find(const char *name, int flag)
void BKE_studiolight_free()
static void studiolight_add_files_from_datafolder(const int folder_id, const char *subfolder, int flag)
#define WRITE_VEC3(str, id, val)
void BKE_studiolight_init()
BLI_INLINE float area_element(float x, float y)
void BKE_studiolight_default(SolidLight lights[4], float light_ambient[3])
StudioLight * BKE_studiolight_findindex(int index, int flag)
static void studiolight_load_solid_light(StudioLight *sl)
static float wrapped_lighting(float NL, float w)
#define STUDIOLIGHT_DELETE_ICON(s)
static void studiolight_free_image_buffers(StudioLight *sl)
#define STUDIOLIGHT_PASSNAME_SPECULAR
static const char * STUDIOLIGHT_WORLD_FOLDER
static void studiolight_create_matcap_diffuse_gputexture(StudioLight *sl)
#define READ_VEC3(id, val, lines)
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
ListBase * BKE_studiolight_listbase()
StudioLight * BKE_studiolight_create(const char *filepath, const SolidLight light[4], const float light_ambient[3])
static const char * STUDIOLIGHT_MATCAP_FOLDER
static void studiolight_create_equirect_radiance_gputexture(StudioLight *sl)
static float brdf_approx(float spec_color, float roughness, float NV)
#define GPU_TEXTURE_SAFE_FREE(p)
static void direction_to_equirect(float r[2], const float dir[3])
static void studiolight_write_solid_light(StudioLight *sl)
static const char * STUDIOLIGHT_WORLD_DEFAULT
static void * studiolight_multilayer_addview(void *, const char *)
#define READ_SOLIDLIGHT(sl, i, lines)
static void studiolight_matcap_preview(uint *icon_buffer, StudioLight *sl, bool flipped)
void BKE_studiolight_refresh()
static float blinn_specular(const float L[3], const float I[3], const float N[3], const float R[3], float NL, float roughness, float wrap)
void BKE_studiolight_preview(uint *icon_buffer, StudioLight *sl, int icon_id_type)