Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2018-05-25 09:06:36 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2018-05-28 18:07:39 +0300
commit765fd29d6855d098d8fcdd72ba595dfd1e4e4e17 (patch)
treef1877bfcaf5f4a309f294e2fb516a61c9d6f01aa /source/blender/blenkernel
parentce5fa2decad115f023e2f5591255078768b4fa5e (diff)
EEvEE: LookDev
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_icons.h2
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h17
-rw-r--r--source/blender/blenkernel/intern/icons.c5
-rw-r--r--source/blender/blenkernel/intern/studiolight.c219
4 files changed, 183 insertions, 60 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index e54531bdb0e..22897d2ea80 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -160,7 +160,7 @@ struct ImBuf *BKE_icon_geom_rasterize(
const struct Icon_Geom *geom,
const unsigned int size_x, const unsigned int size_y);
-int BKE_icon_ensure_studio_light(struct StudioLight *sl);
+int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type);
#define ICON_RENDER_DEFAULT_HEIGHT 32
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index 2fcf6ab2f19..213de712abd 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -51,6 +51,10 @@
#define STUDIOLIGHT_Y_NEG 3
#define STUDIOLIGHT_Z_POS 4
#define STUDIOLIGHT_Z_NEG 5
+#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE 0
+#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE 1
+
+struct GPUTexture;
enum StudioLightFlag {
STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0),
@@ -58,7 +62,9 @@ enum StudioLightFlag {
STUDIOLIGHT_EXTERNAL_FILE = (1 << 2),
STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3),
STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4),
- STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 5),
+ STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED = (1 << 5),
+ STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE = (1 << 6),
+ STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 7),
} StudioLightFlag;
typedef struct StudioLight {
@@ -66,18 +72,21 @@ typedef struct StudioLight {
int flag;
char name[FILE_MAXFILE];
char path[FILE_MAX];
- int icon_id;
+ int irradiance_icon_id;
+ int radiance_icon_id;
int index;
float diffuse_light[6][3];
float light_direction[3];
+ ImBuf *equirectangular_buffer;
ImBuf *radiance_buffers[6];
+ struct GPUTexture *equirectangular_gputexture;
} StudioLight;
void BKE_studiolight_init(void);
void BKE_studiolight_free(void);
-struct StudioLight *BKE_studiolight_find(const char *name);
+struct StudioLight *BKE_studiolight_find(const char *name, int flag);
struct StudioLight *BKE_studiolight_findindex(int index);
-unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size);
+unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type);
const struct ListBase *BKE_studiolight_listbase(void);
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag);
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index bfd4e07606f..e409f8c91f0 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -806,10 +806,11 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
/** \name Studio Light Icon
* \{ */
-int BKE_icon_ensure_studio_light(struct StudioLight *sl)
+int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
{
int icon_id = get_next_free_id();
- icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
+ Icon *icon = icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
+ icon->id_type = id_type;
return icon_id;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index d9ff6e84ac2..f139ea5fbe6 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -48,6 +48,8 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "GPU_texture.h"
+
#include "MEM_guardedalloc.h"
@@ -67,6 +69,16 @@ static void studiolight_free(struct StudioLight *sl)
IMB_freeImBuf(sl->radiance_buffers[index]);
sl->radiance_buffers[index] = NULL;
}
+
+ if (sl->equirectangular_gputexture) {
+ GPU_texture_free(sl->equirectangular_gputexture);
+ sl->equirectangular_gputexture = NULL;
+ }
+
+ if (sl->equirectangular_buffer) {
+ IMB_freeImBuf(sl->equirectangular_buffer);
+ sl->equirectangular_buffer = NULL;
+ }
}
MEM_freeN(sl);
}
@@ -78,7 +90,8 @@ static struct StudioLight *studiolight_create(void)
sl->name[0] = 0x00;
sl->flag = 0;
sl->index = BLI_listbase_count(&studiolights);
- sl->icon_id = BKE_icon_ensure_studio_light(sl);
+ sl->radiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_RADIANCE);
+ sl->irradiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE);
for (int index = 0 ; index < 6 ; index ++) {
sl->radiance_buffers[index] = NULL;
@@ -133,13 +146,38 @@ static void studiolight_calculate_radiance_buffer(
}
}
-static void studiolight_calculate_radiance_buffers(StudioLight *sl)
+static void studiolight_load_equierectangular_image(StudioLight *sl)
{
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
ImBuf *ibuf = NULL;
ibuf = IMB_loadiffname(sl->path, 0, NULL);
if (ibuf) {
IMB_float_from_rect(ibuf);
+ sl->equirectangular_buffer = ibuf;
+ }
+ }
+ sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED;
+}
+
+static void studiolight_create_equierectangular_gputexture(StudioLight *sl)
+{
+ if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
+ char error[256];
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ ImBuf *ibuf = sl->equirectangular_buffer;
+ sl->equirectangular_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA16F, ibuf->rect_float, error);
+ }
+ sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE;
+}
+
+
+
+static void studiolight_calculate_radiance_buffers(StudioLight *sl)
+{
+ if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ ImBuf* ibuf = sl->equirectangular_buffer;
+ if (ibuf) {
float *colbuf = MEM_mallocN(SQUARE(STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * sizeof(float[4]), __func__);
const float add = 1.0f / (STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE + 1);
const float start = ((1.0f / STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * 0.5f) - 0.5f;
@@ -183,7 +221,6 @@ static void studiolight_calculate_radiance_buffers(StudioLight *sl)
IMB_saveiff(sl->radiance_buffers[STUDIOLIGHT_Z_NEG], "/tmp/studiolight_radiance_top.png", IB_rectfloat);
#endif
MEM_freeN(colbuf);
- IMB_freeImBuf(ibuf);
}
}
sl->flag |= STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED;
@@ -451,6 +488,114 @@ static int studiolight_cmp(const void *a, const void *b)
return BLI_strcasecmp(sl1->name, sl2->name);
}
}
+
+/* icons */
+static unsigned int* studiolight_radiance_preview(StudioLight *sl, int icon_size)
+{
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+
+ uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+ int icon_center = icon_size / 2;
+ float sphere_radius = icon_center * 0.9;
+
+ int offset = 0;
+ for (int y = 0; y < icon_size; y++) {
+ float dy = y - icon_center;
+ for (int x = 0; x < icon_size; x++) {
+ float dx = x - icon_center;
+ /* calculate aliasing */
+ float alias = 0;
+ const float alias_step = 0.333;
+ for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
+ for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
+ if (sqrt(ay * ay + ax * ax) < sphere_radius) {
+ alias += alias_step * alias_step;
+ }
+ }
+ }
+ uint pixelresult = 0x0;
+ uint alias_i = clamp_i(alias * 256, 0, 255);
+ if (alias_i != 0) {
+ /* calculate normal */
+ uint alias_mask = alias_i << 24;
+ float incoming[3];
+ copy_v3_fl3(incoming, 0.0, 1.0, 0.0);
+
+ float normal[3];
+ normal[0] = dx / sphere_radius;
+ normal[2] = dy / sphere_radius;
+ normal[1] = -sqrt(-(normal[0] * normal[0]) - (normal[2] * normal[2]) + 1);
+ normalize_v3(normal);
+
+ float direction[3];
+ reflect_v3_v3v3(direction, incoming, normal);
+
+ float color[4];
+ studiolight_calculate_radiance(sl->equirectangular_buffer, color, direction);
+
+ pixelresult = rgb_to_cpack(
+ linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])) | alias_mask;
+ }
+ rect[offset++] = pixelresult;
+ }
+ }
+ return rect;
+}
+
+static unsigned int* studiolight_irradiance_preview(StudioLight *sl, int icon_size)
+{
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
+
+ uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+ int icon_center = icon_size / 2;
+ float sphere_radius = icon_center * 0.9;
+
+ int offset = 0;
+ for (int y = 0; y < icon_size; y++) {
+ float dy = y - icon_center;
+ for (int x = 0; x < icon_size; x++) {
+ float dx = x - icon_center;
+ /* calculate aliasing */
+ float alias = 0;
+ const float alias_step = 0.333;
+ for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
+ for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
+ if (sqrt(ay * ay + ax * ax) < sphere_radius) {
+ alias += alias_step * alias_step;
+ }
+ }
+ }
+ uint pixelresult = 0x0;
+ uint alias_i = clamp_i(alias * 256, 0, 255);
+ if (alias_i != 0) {
+ /* calculate normal */
+ uint alias_mask = alias_i << 24;
+ float normal[3];
+ normal[0] = dx / sphere_radius;
+ normal[1] = dy / sphere_radius;
+ normal[2] = sqrt(-(normal[0] * normal[0]) - (normal[1] * normal[1]) + 1);
+ normalize_v3(normal);
+
+ float color[3];
+ mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0));
+
+ pixelresult = rgb_to_cpack(
+ linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])) | alias_mask;
+ }
+ rect[offset++] = pixelresult;
+ }
+ }
+ return rect;
+}
+
/* API */
void BKE_studiolight_init(void)
{
@@ -487,11 +632,16 @@ void BKE_studiolight_free(void)
}
}
-struct StudioLight *BKE_studiolight_find(const char *name)
+struct StudioLight *BKE_studiolight_find(const char *name, int flag)
{
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
- return sl;
+ if ((sl->flag & flag) == flag) {
+ return sl;
+ } else {
+ /* flags do not match, so use default */
+ return studiolights.first;
+ }
}
}
/* When not found, use the default studio light */
@@ -514,56 +664,13 @@ const struct ListBase *BKE_studiolight_listbase(void)
return &studiolights;
}
-unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size)
+unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type)
{
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
-
- uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
- int icon_center = icon_size / 2;
- float sphere_radius = icon_center * 0.9;
-
- int offset = 0;
- for (int y = 0; y < icon_size; y++) {
- float dy = y - icon_center;
- for (int x = 0; x < icon_size; x++) {
- float dx = x - icon_center;
- /* calculate aliasing */
- float alias = 0;
- const float alias_step = 0.333;
- for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
- for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
- if (sqrt(ay * ay + ax * ax) < sphere_radius) {
- alias += alias_step * alias_step;
- }
- }
- }
- uint pixelresult = 0x0;
- uint alias_i = clamp_i(alias * 256, 0, 255);
- if (alias_i != 0) {
- /* calculate normal */
- uint alias_mask = alias_i << 24;
- float normal[3];
- normal[0] = dx / sphere_radius;
- normal[1] = dy / sphere_radius;
- normal[2] = sqrt(-(normal[0] * normal[0]) - (normal[1] * normal[1]) + 1);
- normalize_v3(normal);
-
- float color[3];
- mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0));
-
- pixelresult = rgb_to_cpack(
- linearrgb_to_srgb(color[0]),
- linearrgb_to_srgb(color[1]),
- linearrgb_to_srgb(color[2])) | alias_mask;
- }
- rect[offset++] = pixelresult;
- }
+ if (icon_id_type == STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE) {
+ return studiolight_irradiance_preview(sl, icon_size);
+ } else {
+ return studiolight_radiance_preview(sl, icon_size);
}
- return rect;
}
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
@@ -572,12 +679,18 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
return;
}
+ if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED)) {
+ studiolight_load_equierectangular_image(sl);
+ }
if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) {
studiolight_calculate_radiance_buffers(sl);
}
if ((flag & STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED)) {
studiolight_calculate_diffuse_light(sl);
}
+ if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE)) {
+ studiolight_create_equierectangular_gputexture(sl);
+ }
if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) {
studiolight_calculate_light_direction(sl);
}