Workbench: Matcaps T55291
authorJeroen Bakker <j.bakker@atmind.nl>
Tue, 5 Jun 2018 06:15:30 +0000 (08:15 +0200)
committerJeroen Bakker <j.bakker@atmind.nl>
Tue, 5 Jun 2018 09:38:33 +0000 (11:38 +0200)
- users can use their own matcaps
.config/blender/2.80/datafiles/studiolights/matcap/ folder
- upto 100 matcaps can be loaded
- color of the matcap is influenced by the color of the material/single
color etc. To show the plain matcap use single color at 1.0
- chosing a matcap is at lighting level (flat/studio/matcap)
- matcap only possible in solid mode
- also works for X-Ray mode

As the old matcaps are still in used by the clay engine I didn't remove
it yet.

41 files changed:
release/datafiles/studiolights/matcap/license.txt [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc01.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc02.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc03.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc04.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc05.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc06.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc07.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc08.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc09.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc10.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc11.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc12.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc13.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc14.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc15.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc16.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc17.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc18.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc19.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc20.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc21.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc22.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc23.jpg [new file with mode: 0644]
release/datafiles/studiolights/matcap/mc24.jpg [new file with mode: 0644]
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_studiolight.h
source/blender/blenkernel/intern/studiolight.c
source/blender/blenloader/intern/versioning_280.c
source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
source/blender/draw/engines/workbench/workbench_data.c
source/blender/draw/engines/workbench/workbench_deferred.c
source/blender/draw/engines/workbench/workbench_forward.c
source/blender/draw/engines/workbench/workbench_materials.c
source/blender/draw/engines/workbench/workbench_private.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesrna/intern/rna_space.c

diff --git a/release/datafiles/studiolights/matcap/license.txt b/release/datafiles/studiolights/matcap/license.txt
new file mode 100644 (file)
index 0000000..358c8dc
--- /dev/null
@@ -0,0 +1,3 @@
+These matcap images are licensed as GNU GPL 2 or later, like the rest of Blender's code.
+
+Thanks to Kent Trammell, Aidy Burrows, John Herreno , Terry Wallwork and David Silverman for making the pictures.
diff --git a/release/datafiles/studiolights/matcap/mc01.jpg b/release/datafiles/studiolights/matcap/mc01.jpg
new file mode 100644 (file)
index 0000000..8c7aef2
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc01.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc02.jpg b/release/datafiles/studiolights/matcap/mc02.jpg
new file mode 100644 (file)
index 0000000..11deddf
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc02.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc03.jpg b/release/datafiles/studiolights/matcap/mc03.jpg
new file mode 100644 (file)
index 0000000..64d992f
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc03.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc04.jpg b/release/datafiles/studiolights/matcap/mc04.jpg
new file mode 100644 (file)
index 0000000..42be580
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc04.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc05.jpg b/release/datafiles/studiolights/matcap/mc05.jpg
new file mode 100644 (file)
index 0000000..586d233
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc05.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc06.jpg b/release/datafiles/studiolights/matcap/mc06.jpg
new file mode 100644 (file)
index 0000000..657883d
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc06.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc07.jpg b/release/datafiles/studiolights/matcap/mc07.jpg
new file mode 100644 (file)
index 0000000..372caf7
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc07.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc08.jpg b/release/datafiles/studiolights/matcap/mc08.jpg
new file mode 100644 (file)
index 0000000..50eec40
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc08.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc09.jpg b/release/datafiles/studiolights/matcap/mc09.jpg
new file mode 100644 (file)
index 0000000..e05d441
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc09.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc10.jpg b/release/datafiles/studiolights/matcap/mc10.jpg
new file mode 100644 (file)
index 0000000..ab82f17
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc10.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc11.jpg b/release/datafiles/studiolights/matcap/mc11.jpg
new file mode 100644 (file)
index 0000000..053550f
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc11.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc12.jpg b/release/datafiles/studiolights/matcap/mc12.jpg
new file mode 100644 (file)
index 0000000..beb16f3
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc12.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc13.jpg b/release/datafiles/studiolights/matcap/mc13.jpg
new file mode 100644 (file)
index 0000000..7fb8fa5
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc13.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc14.jpg b/release/datafiles/studiolights/matcap/mc14.jpg
new file mode 100644 (file)
index 0000000..ba868d2
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc14.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc15.jpg b/release/datafiles/studiolights/matcap/mc15.jpg
new file mode 100644 (file)
index 0000000..b10ea32
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc15.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc16.jpg b/release/datafiles/studiolights/matcap/mc16.jpg
new file mode 100644 (file)
index 0000000..c6ce02d
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc16.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc17.jpg b/release/datafiles/studiolights/matcap/mc17.jpg
new file mode 100644 (file)
index 0000000..14f15f7
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc17.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc18.jpg b/release/datafiles/studiolights/matcap/mc18.jpg
new file mode 100644 (file)
index 0000000..db57285
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc18.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc19.jpg b/release/datafiles/studiolights/matcap/mc19.jpg
new file mode 100644 (file)
index 0000000..56d2efb
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc19.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc20.jpg b/release/datafiles/studiolights/matcap/mc20.jpg
new file mode 100644 (file)
index 0000000..002a091
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc20.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc21.jpg b/release/datafiles/studiolights/matcap/mc21.jpg
new file mode 100644 (file)
index 0000000..cb2fea5
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc21.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc22.jpg b/release/datafiles/studiolights/matcap/mc22.jpg
new file mode 100644 (file)
index 0000000..2fc71b9
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc22.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc23.jpg b/release/datafiles/studiolights/matcap/mc23.jpg
new file mode 100644 (file)
index 0000000..3793c0f
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc23.jpg differ
diff --git a/release/datafiles/studiolights/matcap/mc24.jpg b/release/datafiles/studiolights/matcap/mc24.jpg
new file mode 100644 (file)
index 0000000..2a9618d
Binary files /dev/null and b/release/datafiles/studiolights/matcap/mc24.jpg differ
index ea3a804e7c3dd37d3a1ce63c509dddfff0e2ddb2..68719170a7040c184773c5c96eb53851b940d84b 100644 (file)
@@ -3518,12 +3518,6 @@ class VIEW3D_PT_shading(Panel):
 
         col = layout.column()
 
-        if shading.type == 'SOLID':
-            col.row().prop(shading, "color_type", expand=True)
-
-            if shading.color_type == 'SINGLE':
-                col.row().prop(shading, "single_color", text="")
-
         if shading.type in ('SOLID', 'TEXTURED'):
             col.row().prop(shading, "light", expand=True)
             if shading.light == 'STUDIO':
@@ -3531,11 +3525,20 @@ class VIEW3D_PT_shading(Panel):
                 if shading.studio_light_orientation == 'WORLD':
                     col.row().prop(shading, "studiolight_rot_z")
 
+            elif shading.light == 'MATCAP':
+                col.row().template_icon_view(shading, "matcap")
+
+        if shading.type == 'SOLID':
+            col.row().prop(shading, "color_type", expand=True)
+
+            if shading.color_type == 'SINGLE':
+                col.row().prop(shading, "single_color", text="")
+
+        if not(shading.type == 'SOLID' and shading.light == 'MATCAP'):
             row = col.row()
             row.prop(shading, "show_specular_highlight")
 
-            col.separator()
-
+        if shading.type in ('SOLID', 'TEXTURED'):
             row = col.row()
             row.prop(shading, "show_xray")
             sub = row.row()
index 2f2e948ab267f6236e331a49220a3b19ff015a4c..9bf9f0ea904eb2b1ae97f46af0ff50c7cb456f6d 100644 (file)
@@ -59,15 +59,21 @@ struct GPUTexture;
 enum StudioLightFlag {
        STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED                    = (1 << 0),
        STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED                  = (1 << 1),
-       STUDIOLIGHT_EXTERNAL_FILE                               = (1 << 2),
-       STUDIOLIGHT_ORIENTATION_CAMERA                          = (1 << 3),
-       STUDIOLIGHT_ORIENTATION_WORLD                           = (1 << 4),
-       STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED                = (1 << 5),
-       STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_IMAGE_CALCULATED = (1 << 6),
-       STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE         = (1 << 7),
-       STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE       = (1 << 8),
-       STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED                 = (1 << 9),
+       STUDIOLIGHT_INTERNAL                                    = (1 << 2),
+       STUDIOLIGHT_EXTERNAL_FILE                               = (1 << 3),
+       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_RADIANCE_BUFFERS_CALCULATED                 = (1 << 11),
 } StudioLightFlag;
+#define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE)
+#define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL)
+#define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD)
+#define STUDIOLIGHT_ORIENTATIONS_SOLID (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD)
 
 typedef struct StudioLight {
        struct StudioLight *next, *prev;
@@ -89,7 +95,8 @@ typedef struct StudioLight {
 void BKE_studiolight_init(void);
 void BKE_studiolight_free(void);
 struct StudioLight *BKE_studiolight_find(const char *name, int flag);
-struct StudioLight *BKE_studiolight_findindex(int index);
+struct StudioLight *BKE_studiolight_findindex(int index, int flag);
+struct StudioLight *BKE_studiolight_find_first(int flag);
 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);
index 4ef7b3d224711a1306345e2a501bc11d39418cd7..0d44509ae652a50a85ed935c48aebc94c4e5856c 100644 (file)
@@ -62,6 +62,7 @@ static ListBase studiolights;
 
 static const char *STUDIOLIGHT_CAMERA_FOLDER = "studiolights/camera/";
 static const char *STUDIOLIGHT_WORLD_FOLDER = "studiolights/world/";
+static const char *STUDIOLIGHT_MATCAP_FOLDER = "studiolights/matcap/";
 
 /* FUNCTIONS */
 static void studiolight_free(struct StudioLight *sl)
@@ -168,16 +169,16 @@ static void studiolight_load_equierectangular_image(StudioLight *sl)
                        sl->equirectangular_radiance_buffer = ibuf;
                }
        }
-       sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED;
+       sl->flag |= STUDIOLIGHT_EXTERNAL_IMAGE_LOADED;
 }
 
 static void studiolight_create_equierectangular_radiance_gputexture(StudioLight *sl)
 {
        if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
                char error[256];
-               BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+               BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
                ImBuf *ibuf = sl->equirectangular_radiance_buffer;
-               sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA16F, ibuf->rect_float, error);
+               sl->equirectangular_radiance_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA8, ibuf->rect_float, error);
                GPUTexture *tex = sl->equirectangular_radiance_gputexture;
                GPU_texture_bind(tex, 0);
                GPU_texture_filter_mode(tex, true);
@@ -206,7 +207,7 @@ static void studiolight_create_equierectangular_irradiance_gputexture(StudioLigh
 static void studiolight_calculate_radiance_cubemap_buffers(StudioLight *sl)
 {
        if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
-               BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+               BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
                ImBuf *ibuf = sl->equirectangular_radiance_buffer;
                if (ibuf) {
                        float *colbuf = MEM_mallocN(SQUARE(STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * sizeof(float[4]), __func__);
@@ -527,7 +528,7 @@ static int studiolight_cmp(const void *a, const void *b)
 /* icons */
 static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size)
 {
-       BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+       BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
 
        uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
        int icon_center = icon_size / 2;
@@ -579,6 +580,27 @@ static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size)
        return rect;
 }
 
+static uint *studiolight_matcap_preview(StudioLight *sl, int icon_size)
+{
+       BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED);
+
+       uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+       int offset = 0;
+       ImBuf* ibuf = sl->equirectangular_radiance_buffer;
+       for (int y= 0; y < icon_size; y ++)
+       {
+               for (int x = 0; x < icon_size; x ++)
+               {
+                       uint pixelresult = 0x0;
+                       float fx = x * ibuf->x / icon_size;
+                       float fy = y * ibuf->y / icon_size;
+                       nearest_interpolation_color(ibuf, (unsigned char*)&pixelresult, NULL, fx, fy);
+                       rect[offset++] = pixelresult;
+               }
+       }
+       return rect;
+}
+
 static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size)
 {
        if (/*!(sl->flag & STUDIOLIGHT_EXTERNAL_FILE)*/ 1) {
@@ -696,7 +718,7 @@ void BKE_studiolight_init(void)
        /* Add default studio light */
        sl = studiolight_create();
        BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE);
-       sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
+       sl->flag = STUDIOLIGHT_INTERNAL | STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
        copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f);
        copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f);
        copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 0.8f);
@@ -709,6 +731,8 @@ void BKE_studiolight_init(void)
        studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES,   STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
        studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER,  STUDIOLIGHT_ORIENTATION_WORLD);
        studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES,   STUDIOLIGHT_WORLD_FOLDER,  STUDIOLIGHT_ORIENTATION_WORLD);
+       studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+       studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES,   STUDIOLIGHT_MATCAP_FOLDER, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
 
        /* sort studio lights on filename. */
        BLI_listbase_sort(&studiolights, studiolight_cmp);
@@ -722,24 +746,34 @@ void BKE_studiolight_free(void)
        }
 }
 
+struct StudioLight *BKE_studiolight_find_first(int flag)
+{
+       LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
+               if ((sl->flag & flag)) {
+                       return sl;
+               }
+       }
+       return NULL;
+}
+
 struct StudioLight *BKE_studiolight_find(const char *name, int flag)
 {
        LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
                if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
-                       if ((sl->flag & flag) == flag) {
+                       if ((sl->flag & flag)) {
                                return sl;
                        }
                        else {
                                /* flags do not match, so use default */
-                               return studiolights.first;
+                               return BKE_studiolight_find_first(flag);
                        }
                }
        }
        /* When not found, use the default studio light */
-       return studiolights.first;
+       return BKE_studiolight_find_first(flag);
 }
 
-struct StudioLight *BKE_studiolight_findindex(int index)
+struct StudioLight *BKE_studiolight_findindex(int index, int flag)
 {
        LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
                if (sl->index == index) {
@@ -747,7 +781,7 @@ struct StudioLight *BKE_studiolight_findindex(int index)
                }
        }
        /* When not found, use the default studio light */
-       return studiolights.first;
+       return BKE_studiolight_find_first(flag);
 }
 
 const struct ListBase *BKE_studiolight_listbase(void)
@@ -758,7 +792,12 @@ const struct ListBase *BKE_studiolight_listbase(void)
 uint *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type)
 {
        if (icon_id_type == STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE) {
-               return studiolight_irradiance_preview(sl, icon_size);
+               if (sl->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL) {
+                       return studiolight_matcap_preview(sl, icon_size);
+               }
+               else {
+                       return studiolight_irradiance_preview(sl, icon_size);
+               }
        }
        else {
                return studiolight_radiance_preview(sl, icon_size);
@@ -771,7 +810,7 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
                return;
        }
 
-       if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED)) {
+       if ((flag & STUDIOLIGHT_EXTERNAL_IMAGE_LOADED)) {
                studiolight_load_equierectangular_image(sl);
        }
        if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) {
index 144b3889d303a1f144eec0461564eaf77d416ff5..7827e79304949f1f4a3b74f810eb2e3078c694b3 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
+#include "BKE_studiolight.h"
 #include "BKE_workspace.h"
 
 #include "BLO_readfile.h"
@@ -1536,5 +1537,21 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
                                }
                        }
                }
+               if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "char", "matcap")) {
+                       StudioLight *default_matcap = BKE_studiolight_find_first(STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+                       /* when loading the internal file is loaded before the matcaps */
+                       if (default_matcap) {
+                               for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
+                                       for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+                                               for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+                                                       if (sl->spacetype == SPACE_VIEW3D) {
+                                                               View3D *v3d = (View3D *)sl;
+                                                               BLI_strncpy(v3d->shading.matcap, default_matcap->name, FILE_MAXFILE);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
        }
 }
index fc076ee8117b694b39f0e4001683b019c91769e0..8d648ce7d7bb9e8e758d90abb1211735306447c8 100644 (file)
@@ -23,4 +23,5 @@ struct MaterialData {
        vec4 diffuse_color;
        vec4 specular_color;
        float roughness;
+       int matcap_texture_index;
 };
index 5f37490603d558c7696adb47412186606f52e69e..326837bc69fd981d963a34b316caeb05864b66ec 100644 (file)
@@ -11,6 +11,9 @@ uniform float lightMultiplier;
 uniform float shadowShift = 0.1;
 uniform mat3 normalWorldMatrix;
 
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+uniform sampler2D matcapImage;
+#endif
 
 layout(std140) uniform world_block {
        WorldData world_data;
@@ -43,16 +46,21 @@ void main()
 #endif /* !V3D_SHADING_OBJECT_OUTLINE */
 
        vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
+
 /* Do we need normals */
 #ifdef NORMAL_VIEWPORT_PASS_ENABLED
-#ifdef WORKBENCH_ENCODE_NORMALS
+#  ifdef WORKBENCH_ENCODE_NORMALS
        vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
        if (diffuse_color.a == 0.0) {
                normal_viewport = -normal_viewport;
        }
-#else /* WORKBENCH_ENCODE_NORMALS */
+#  else /* WORKBENCH_ENCODE_NORMALS */
        vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
-#endif /* WORKBENCH_ENCODE_NORMALS */
+#  endif /* WORKBENCH_ENCODE_NORMALS */
+#endif
+
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+       diffuse_color = texture(matcapImage, normal_viewport.xy / 2.0 + 0.5);
 #endif
 
 #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
@@ -64,22 +72,27 @@ void main()
        vec3 specular_color = vec3(0.0);
 #endif
 
+#ifdef V3D_LIGHTING_FLAT
+       vec3 diffuse_light = vec3(1.0);
+#endif
+
+#ifdef V3D_LIGHTING_MATCAP
+       /* TODO: if pixel data is matcap. then */
+       vec3 diffuse_light = texelFetch(specularBuffer, texel, 0).rgb;
+#endif
+
 #ifdef V3D_LIGHTING_STUDIO
-  #ifdef STUDIOLIGHT_ORIENTATION_CAMERA
+#  ifdef STUDIOLIGHT_ORIENTATION_CAMERA
        vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
-  #endif
+#  endif
 
-  #ifdef STUDIOLIGHT_ORIENTATION_WORLD
+#  ifdef STUDIOLIGHT_ORIENTATION_WORLD
        vec3 normal_world = normalWorldMatrix * normal_viewport;
        vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
-  #endif
+#  endif
+#endif
        vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
 
-#else /* V3D_LIGHTING_STUDIO */
-       vec3 shaded_color = diffuse_color.rgb + specular_color;
-
-#endif /* V3D_LIGHTING_STUDIO */
-
 #ifdef V3D_SHADING_SHADOW
        float light_factor = -dot(normal_viewport, world_data.light_direction_vs.xyz);
        /* The step function might be ok for meshes but it's
index a9c84e11aa66124a5924d59314509ea99ea5f299..e04bffdeea5503516d4196e12968cca3c0f3cfb7 100644 (file)
@@ -10,6 +10,9 @@ in vec3 normal_viewport;
 #ifdef OB_TEXTURE
 in vec2 uv_interp;
 #endif
+#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+uniform sampler2D matcapImage;
+#endif
 
 layout(std140) uniform world_block {
        WorldData world_data;
@@ -25,6 +28,7 @@ layout(location=0) out vec4 transparentAccum;
 void main()
 {
        vec4 diffuse_color;
+       vec3 diffuse_light = vec3(1.0);
 #ifdef OB_SOLID
        diffuse_color = material_data.diffuse_color;
 #endif /* OB_SOLID */
@@ -32,6 +36,10 @@ void main()
        diffuse_color = texture(image, uv_interp);
 #endif /* OB_TEXTURE */
 
+#ifdef V3D_LIGHTING_MATCAP
+       diffuse_light = texture(matcapImage, normal_viewport.xy / 2.0 + 0.5).rgb;
+#endif
+
 #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
        vec3 specular_color = get_world_specular_lights(world_data, vec4(material_data.specular_color.rgb, material_data.roughness), normal_viewport, vec3(0.0, 0.0, 1.0));
 #else
@@ -40,17 +48,16 @@ void main()
 
 #ifdef V3D_LIGHTING_STUDIO
 #  ifdef STUDIOLIGHT_ORIENTATION_CAMERA
-       vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
+       diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
 #  endif
 #  ifdef STUDIOLIGHT_ORIENTATION_WORLD
        vec3 normal_world = normalWorldMatrix * normal_viewport;
-       vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
+       diffuse_light = get_world_diffuse_light(world_data, normal_world);
 #  endif
-       vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
-#else
-       vec3 shaded_color = diffuse_color.rgb + specular_color;
 #endif
 
+       vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
+
        vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha);
        transparentAccum = calculate_transparent_accum(premultiplied);
 }
index bc7741f853c9a95b176f2ed5930720c0144f23a1..5931a11f184819c06c8d7bee91a0fcc471ec0968 100644 (file)
@@ -24,19 +24,29 @@ layout(location=0) out uint objectId;
 layout(location=1) out vec4 diffuseColor;
 layout(location=2) out vec4 specularColor;
 #ifdef NORMAL_VIEWPORT_PASS_ENABLED
-       #ifdef WORKBENCH_ENCODE_NORMALS
+#  ifdef WORKBENCH_ENCODE_NORMALS
 layout(location=3) out vec2 normalViewport;
-       #else /* WORKBENCH_ENCODE_NORMALS */
+#  else /* WORKBENCH_ENCODE_NORMALS */
 layout(location=3) out vec3 normalViewport;
-       #endif /* WORKBENCH_ENCODE_NORMALS */
+#  endif /* WORKBENCH_ENCODE_NORMALS */
 #endif /* NORMAL_VIEWPORT_PASS_ENABLED */
 
 void main()
 {
        objectId = uint(object_id);
+
+#ifdef NORMAL_VIEWPORT_PASS_ENABLED
+       vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport;
+       n = normalize(n);
+#endif
+
 #ifdef OB_SOLID
        diffuseColor = vec4(material_data.diffuse_color.rgb, 0.0);
+#  ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
+       specularColor = vec4(material_data.diffuse_color.rgb, material_data.matcap_texture_index);
+#  endif
 #endif /* OB_SOLID */
+
 #ifdef OB_TEXTURE
        diffuseColor = texture(image, uv_interp);
 #endif /* OB_TEXTURE */
@@ -47,14 +57,12 @@ void main()
 
 #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
        specularColor = vec4(material_data.specular_color.rgb, material_data.roughness);
-#ifdef HAIR_SHADER
+#  ifdef HAIR_SHADER
        specularColor.rgb = clamp(specularColor.rgb - hair_color_variation, 0.0, 1.0);
-#endif
+#  endif
 #endif
 
 #ifdef NORMAL_VIEWPORT_PASS_ENABLED
-       vec3 n = (gl_FrontFacing) ? normal_viewport : -normal_viewport;
-       n = normalize(n);
 #  ifdef WORKBENCH_ENCODE_NORMALS
        diffuseColor.a = float(gl_FrontFacing);
        normalViewport = normal_encode(n);
index be124257c3334de9aee41a5bd30f31c8daa8849b..6f4237ebd0af136852c24c45d86594ffa7b30ea8 100644 (file)
@@ -29,7 +29,7 @@ vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N,
 
        float shininess = exp2(10*(1.0-specular_data.a) + 1);
 
-#ifdef BLINN
+#  ifdef BLINN
        float normalization_factor = (shininess + 8) / (8 * M_PI);
        vec3 L = -light_data.light_direction_vs.xyz;
        vec3 halfDir = normalize(L + I);
@@ -37,11 +37,11 @@ vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N,
        float NL = max(dot(L, N), 0.0);
        float specular_influence = pow(specAngle, shininess) * NL  * normalization_factor;
 
-#else
+#  else
        vec3 reflection_vector = reflect(I, N);
        float specAngle = max(dot(light_data.light_direction_vs.xyz, reflection_vector), 0.0);
        float specular_influence = pow(specAngle, shininess);
-#endif
+#  endif
 
        vec3 specular_color = specular_light * specular_influence;
 
index 4ee12a692f54968341c5f8a04200e0aeaf1ba433..4eca3acf238edd2ecc0b5d445d66a3a30047cb9d 100644 (file)
@@ -15,7 +15,11 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
        if (v3d) {
                wpd->shading = v3d->shading;
                wpd->drawtype = v3d->drawtype;
-               wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, 0);
+               if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
+                       wpd->studio_light = BKE_studiolight_find(wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+               } else {
+                       wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD);
+               }
        }
        else {
                memset(&wpd->shading, 0, sizeof(wpd->shading));
@@ -23,7 +27,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
                wpd->shading.shadow_intensity = 0.5;
                copy_v3_fl(wpd->shading.single_color, 0.8f);
                wpd->drawtype = OB_SOLID;
-               wpd->studio_light = BKE_studiolight_findindex(0);
+               wpd->studio_light = BKE_studiolight_find_first(STUDIOLIGHT_INTERNAL);
        }
        wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
 
@@ -71,7 +75,7 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa
                wd->num_lights = 1;
        }
 
-       if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
+       if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
                int light_index = 0;
                for (int index = 0 ; index < 3; index++) {
                        SolidLight *sl = &U.light[index];
index ba5ab7f1cc35b1facd7fc2b036fa5035ac465ca5..285551abb1208c5f4cb202e42aac16cbbf4a7ea0 100644 (file)
@@ -313,7 +313,7 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
        if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
                DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
        }
-       if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+       if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
                DRW_shgroup_uniform_texture_ref(grp, "specularBuffer", &e_data.specular_buffer_tx);
 
 #if 0
@@ -338,6 +338,11 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
        DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
        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);
+       }
+
        workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
 }
 
index 3ed0c207becb8503c0d8ec012a79409125910ec9..931ffc6181078fd20c4173d81a64e4bcb415608e 100644 (file)
@@ -202,7 +202,13 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
                material->material_data.roughness = material_template.material_data.roughness;
                switch (drawtype) {
                        case OB_SOLID:
+                       {
+                               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);
+                               }
                                break;
+                       }
 
                        case OB_TEXTURE:
                        {
index 7c9c7b96b7bbf6224b9d1d7a08fdb5bb38faeb92..2e2e6f8127a7d45547bde181842c300d3746199a 100644 (file)
@@ -52,17 +52,26 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype,
        if (wpd->shading.flag & V3D_SHADING_SHADOW) {
                BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
        }
-       if (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) {
+       if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
                BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
        }
-       if (wpd->shading.light & V3D_LIGHTING_STUDIO) {
+       if (STUDIOLIGHT_ENABLED(wpd)) {
                BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n");
-               if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
-                       BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
-               }
-               else {
-                       BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
-               }
+       }
+       if (FLAT_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_FLAT\n");
+       }
+       if (MATCAP_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_MATCAP\n");
+       }
+       if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_WORLD\n");
+       }
+       if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_CAMERA\n");
+       }
+       if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
+               BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL\n");
        }
        if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
                BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
@@ -94,7 +103,6 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype,
 
 uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
 {
-       /* TODO: make a C-string with settings and hash the string */
        uint input[4];
        uint result;
        float *color = material_template->material_data.diffuse_color;
@@ -121,18 +129,20 @@ uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template)
 int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype, bool is_hair)
 {
        /* NOTE: change MAX_SHADERS accordingly when modifying this function. */
-       const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW | V3D_SHADING_SPECULAR_HIGHLIGHT;
-       int index = (wpd->shading.flag & DRAWOPTIONS_MASK);
-       index = (index << 2) + wpd->shading.light;
-       index = (index << 3);
-       /* set the drawtype flag
-       0 = OB_SOLID,
-       1 = OB_TEXTURE
-       2 = STUDIOLIGHT_ORIENTATION_WORLD
-       */
-       SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 2);
-       SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1);
-       SET_FLAG_FROM_TEST(index, is_hair, 4);
+       int index = 0;
+       /* 1 bit OB_SOLID and OB_TEXTURE */
+       SET_FLAG_FROM_TEST(index, drawtype == OB_TEXTURE, 1 << 0);
+       /* 2 bits FLAT/STUDIO/MATCAP/SCENE */
+       SET_FLAG_FROM_TEST(index, wpd->shading.light, wpd->shading.light << 1);
+       /* 1 bit V3D_SHADING_SPECULAR_HIGHLIGHT */
+       SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT, 1 << 3);
+       SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 4);
+       SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 5);
+       /* 2 bits STUDIOLIGHT_ORIENTATION */
+       SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD, 1 << 6);
+       SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL, 1 << 7);
+       /* 1 bit for hair */
+       SET_FLAG_FROM_TEST(index, is_hair, 1 << 8);
        return index;
 }
 
index 00cb666643090f611da19a283872cf9723166eb5..ac85f4c5296d774b25eb1821344e11da997e82e8 100644 (file)
 
 #define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
 #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
-#define MAX_SHADERS (1 << 10)
-
-
+#define MAX_SHADERS (1 << 9)
+
+#define OB_SOLID_ENABLED(wpd) (wpd->drawtype & OB_SOLID)
+#define OB_TEXTURE_ENABLED(wpd) (wpd->drawtype & OB_TEXTURE)
+#define FLAT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_FLAT)
+#define STUDIOLIGHT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_STUDIO)
+#define MATCAP_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_MATCAP && OB_SOLID_ENABLED(wpd))
+#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD))
+#define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA))
+#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL))
 #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
 #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
-#define SPECULAR_HIGHLIGHT_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT)
-#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED       (wpd))
+#define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)))
+#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd))
 #define NORMAL_ENCODING_ENABLED() (true)
 #define WORKBENCH_REVEALAGE_ENABLED
-#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD)
-#define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA)
 
 
 typedef struct WORKBENCH_FramebufferList {
@@ -127,7 +132,8 @@ typedef struct WORKBENCH_UBO_Material {
        float diffuse_color[4];
        float specular_color[4];
        float roughness;
-       float pad[3];
+       int matcap_texture_index;
+       float pad[2];
 } WORKBENCH_UBO_Material;
 BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_Material, 16)
 
index be980b4fead449bab15228589615b09e22e82de2..68da501d452be081ae7bb2497a24ad77cd4e3e8c 100644 (file)
@@ -140,6 +140,7 @@ typedef struct View3DShading {
        short light;
        char pad[2];
        char studio_light[256]; /* FILE_MAXFILE */
+       char matcap[256]; /* FILE_MAXFILE */
 
        float shadow_intensity;
        float single_color[3];
@@ -333,7 +334,7 @@ typedef struct View3D {
 enum {
        V3D_LIGHTING_FLAT   = 0,
        V3D_LIGHTING_STUDIO = 1,
-       V3D_LIGHTING_SCENE  = 2
+       V3D_LIGHTING_MATCAP = 2,
 };
 
 /* View3DShading->flag */
index b36014370f601aece508b41143cfb98503001fba..46a27ff5d6c88df72df4219bf414263dff91331a 100644 (file)
@@ -196,44 +196,221 @@ const EnumPropertyItem rna_enum_shading_type_items[] = {
 const EnumPropertyItem rna_enum_viewport_lighting_items[] = {
        {V3D_LIGHTING_FLAT,   "FLAT",   0, "Flat Lighting",   "Display using flat lighting"},
        {V3D_LIGHTING_STUDIO, "STUDIO", 0, "Studio Lighting", "Display using studio lighting"},
-       /* {V3D_LIGHTING_SCENE, "SCENE", 0, "Scene Lighting", "Display using scene lighting"}, */
+       {V3D_LIGHTING_MATCAP, "MATCAP", 0, "Matcap",          "Display using matcap material and lighting"},
        {0, NULL, 0, NULL, NULL}
 };
 
+#define DEF_SINGLE_STUDIO_LIGHT_ITEM(value) {value, "STUDIOLIGHT_%%value%%", 0, "", ""}
 static const EnumPropertyItem rna_enum_studio_light_items[] = {
-       {0, "STUDIOLIGHT_00", 0, "", ""},
-       {1, "STUDIOLIGHT_01", 0, "", ""},
-       {2, "STUDIOLIGHT_02", 0, "", ""},
-       {3, "STUDIOLIGHT_03", 0, "", ""},
-       {4, "STUDIOLIGHT_04", 0, "", ""},
-       {5, "STUDIOLIGHT_05", 0, "", ""},
-       {6, "STUDIOLIGHT_06", 0, "", ""},
-       {7, "STUDIOLIGHT_07", 0, "", ""},
-       {8, "STUDIOLIGHT_08", 0, "", ""},
-       {9, "STUDIOLIGHT_09", 0, "", ""},
-       {10, "STUDIOLIGHT_10", 0, "", ""},
-       {11, "STUDIOLIGHT_11", 0, "", ""},
-       {12, "STUDIOLIGHT_12", 0, "", ""},
-       {13, "STUDIOLIGHT_13", 0, "", ""},
-       {14, "STUDIOLIGHT_14", 0, "", ""},
-       {15, "STUDIOLIGHT_15", 0, "", ""},
-       {16, "STUDIOLIGHT_16", 0, "", ""},
-       {17, "STUDIOLIGHT_17", 0, "", ""},
-       {18, "STUDIOLIGHT_18", 0, "", ""},
-       {19, "STUDIOLIGHT_19", 0, "", ""},
-       {20, "STUDIOLIGHT_20", 0, "", ""},
-       {21, "STUDIOLIGHT_21", 0, "", ""},
-       {22, "STUDIOLIGHT_22", 0, "", ""},
-       {23, "STUDIOLIGHT_23", 0, "", ""},
-       {24, "STUDIOLIGHT_24", 0, "", ""},
-       {25, "STUDIOLIGHT_25", 0, "", ""},
-       {26, "STUDIOLIGHT_26", 0, "", ""},
-       {27, "STUDIOLIGHT_27", 0, "", ""},
-       {28, "STUDIOLIGHT_28", 0, "", ""},
-       {29, "STUDIOLIGHT_29", 0, "", ""},
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(0),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(1),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(2),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(3),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(4),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(5),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(6),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(7),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(8),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(9),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(10),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(11),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(12),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(13),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(14),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(15),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(16),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(17),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(18),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(19),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(20),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(21),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(22),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(23),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(24),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(25),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(26),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(27),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(28),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(29),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(30),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(31),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(32),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(33),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(34),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(35),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(36),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(37),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(38),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(39),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(40),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(41),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(42),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(43),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(44),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(45),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(46),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(47),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(48),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(49),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(50),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(51),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(52),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(53),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(54),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(55),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(56),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(57),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(58),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(59),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(60),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(61),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(62),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(63),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(64),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(65),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(66),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(67),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(68),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(69),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(70),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(71),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(72),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(73),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(74),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(75),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(76),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(77),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(78),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(79),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(80),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(81),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(82),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(83),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(84),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(85),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(86),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(87),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(88),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(89),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(90),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(91),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(92),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(93),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(94),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(95),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(96),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(97),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(98),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(99),
        {0, NULL, 0, NULL, NULL}
 };
-#define NUM_STUDIOLIGHT_ITEMS 30
+#define NUM_STUDIOLIGHT_ITEMS 100
+
+static const EnumPropertyItem rna_enum_matcap_items[] = {
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(0),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(1),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(2),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(3),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(4),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(5),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(6),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(7),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(8),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(9),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(10),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(11),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(12),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(13),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(14),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(15),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(16),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(17),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(18),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(19),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(20),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(21),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(22),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(23),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(24),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(25),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(26),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(27),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(28),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(29),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(30),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(31),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(32),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(33),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(34),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(35),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(36),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(37),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(38),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(39),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(40),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(41),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(42),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(43),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(44),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(45),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(46),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(47),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(48),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(49),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(50),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(51),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(52),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(53),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(54),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(55),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(56),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(57),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(58),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(59),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(60),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(61),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(62),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(63),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(64),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(65),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(66),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(67),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(68),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(69),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(70),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(71),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(72),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(73),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(74),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(75),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(76),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(77),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(78),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(79),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(80),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(81),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(82),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(83),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(84),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(85),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(86),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(87),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(88),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(89),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(90),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(91),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(92),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(93),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(94),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(95),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(96),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(97),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(98),
+       DEF_SINGLE_STUDIO_LIGHT_ITEM(99),
+       {0, NULL, 0, NULL, NULL}
+};
+#define NUM_MATCAP_ITEMS 100
+#undef DEF_SINGLE_STUDIO_LIGHT_ITEM
 
 const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
        {SC_MODE_TRACKING, "TRACKING", ICON_ANIM_DATA, "Tracking", "Show tracking and solving tools"},
@@ -547,17 +724,6 @@ static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), Poi
        ED_view3d_shade_update(bmain, v3d, sa);
 }
 
-static void rna_SpaceView3D_matcap_enable(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
-{
-       View3D *v3d = (View3D *)(ptr->data);
-
-       if (v3d->matcap_icon < ICON_MATCAP_01 ||
-           v3d->matcap_icon > ICON_MATCAP_24)
-       {
-               v3d->matcap_icon = ICON_MATCAP_01;
-       }
-}
-
 static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr)
 {
        View3D *v3d = (View3D *)(ptr->data);
@@ -676,6 +842,9 @@ static void rna_3DViewShading_type_set(PointerRNA *ptr, int value)
        if (value != v3d->drawtype && value == OB_RENDER) {
                v3d->prev_drawtype = v3d->drawtype;
        }
+       if (value == OB_TEXTURE && v3d->shading.light == V3D_LIGHTING_MATCAP) {
+               v3d->shading.light = V3D_LIGHTING_STUDIO;
+       }
        v3d->drawtype = value;
 }
 
@@ -713,17 +882,56 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
 static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr)
 {
        View3D *v3d = (View3D *)ptr->data;
-       StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, 0);
-       return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA);
+       StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_FLAG_ALL);
+       return sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS;
 }
 static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value))
 {
 }
 
+/* shading.light */
+static int rna_View3DShading_light_get(PointerRNA *ptr)
+{
+       View3D *v3d = (View3D *)ptr->data;
+       return v3d->shading.light;
+}
+
+static void rna_View3DShading_light_set(PointerRNA *ptr, int value)
+{
+       View3D *v3d = (View3D *)ptr->data;
+       v3d->shading.light = value;
+}
+
+static const EnumPropertyItem *rna_View3DShading_light_itemf(
+        bContext *UNUSED(C), PointerRNA *ptr,
+        PropertyRNA *UNUSED(prop), bool *r_free)
+{
+       View3D *v3d = (View3D *)ptr->data;
+
+       int totitem = 0;
+       EnumPropertyItem *item = NULL;
+
+       if (v3d->drawtype == OB_SOLID || v3d->drawtype == OB_TEXTURE) {
+               RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_FLAT);
+               RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_STUDIO);
+       }
+
+       if (v3d->drawtype == OB_SOLID) {
+               RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_lighting_items, V3D_LIGHTING_MATCAP);
+       }
+       RNA_enum_item_end(&item, &totitem);
+       *r_free = true;
+       return item;
+}
+
+/* Studio light */
 static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
 {
        View3D *v3d = (View3D *)ptr->data;
-       const int flag = (v3d->drawtype == OB_MATERIAL) ? STUDIOLIGHT_ORIENTATION_WORLD : 0;
+       int flag = STUDIOLIGHT_ORIENTATIONS_SOLID;
+       if (v3d->drawtype == OB_MATERIAL) {
+               flag = STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE;
+       }
        StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, flag);
        BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
        return sl->index;
@@ -732,7 +940,7 @@ static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
 static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value)
 {
        View3D *v3d = (View3D *)ptr->data;
-       StudioLight *sl = BKE_studiolight_findindex(value);
+       StudioLight *sl = BKE_studiolight_findindex(value, STUDIOLIGHT_FLAG_ALL);
        BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
 }
 
@@ -750,7 +958,7 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
                show_studiolight = false;
                int icon_id = sl->irradiance_icon_id;
 
-               if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) == 0) {
+               if ((sl->flag & STUDIOLIGHT_INTERNAL)) {
                        /* always show internal lights */
                        show_studiolight = true;
                }
@@ -758,8 +966,9 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
                        switch (v3d->drawtype) {
                                case OB_SOLID:
                                case OB_TEXTURE:
-                                       show_studiolight = true;
+                                       show_studiolight = (sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA)) > 0;
                                        break;
+
                                case OB_MATERIAL:
                                        show_studiolight = (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD) > 0;
                                        icon_id = sl->radiance_icon_id;
@@ -780,6 +989,52 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
        *r_free = true;
        return item;
 }
+/* Matcap studiolight */
+static int rna_View3DShading_matcap_get(PointerRNA *ptr)
+{
+       View3D *v3d = (View3D *)ptr->data;
+       StudioLight *sl = BKE_studiolight_find(v3d->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+       BLI_strncpy(v3d->shading.matcap, sl->name, FILE_MAXFILE);
+       return sl->index;
+}
+
+static void rna_View3DShading_matcap_set(PointerRNA *ptr, int value)
+{
+       View3D *v3d = (View3D *)ptr->data;
+       StudioLight *sl = BKE_studiolight_findindex(value, STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+       BLI_strncpy(v3d->shading.matcap, sl->name, FILE_MAXFILE);
+}
+
+static const EnumPropertyItem *rna_View3DShading_matcap_itemf(
+        bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
+        PropertyRNA *UNUSED(prop), bool *r_free)
+{
+       EnumPropertyItem *item = NULL;
+       EnumPropertyItem *lastitem;
+       int totitem = 0;
+       bool show_studiolight;
+
+       const int flags = (STUDIOLIGHT_EXTERNAL_FILE | STUDIOLIGHT_ORIENTATION_VIEWNORMAL);
+
+       LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) {
+               show_studiolight = false;
+               int icon_id = sl->irradiance_icon_id;
+
+               show_studiolight = (sl->flag & flags) == flags;
+
+               if (show_studiolight && totitem < NUM_MATCAP_ITEMS) {
+                       RNA_enum_items_add_value(&item, &totitem, rna_enum_matcap_items, sl->index);
+                       lastitem = &item[totitem - 1];
+                       lastitem->value = sl->index;
+                       lastitem->icon = icon_id;
+                       lastitem->name = sl->name;
+               }
+       }
+
+       RNA_enum_item_end(&item, &totitem);
+       *r_free = true;
+       return item;
+}
 
 static const EnumPropertyItem *rna_SpaceView3D_stereo3d_camera_itemf(
         bContext *C, PointerRNA *UNUSED(ptr),
@@ -2261,9 +2516,10 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
        };
 
        static const EnumPropertyItem studio_light_orientation_items[] = {
-               {0,                              "UNKNOWN", 0, "Unknown", "Studio light has no orientation"},
-               {STUDIOLIGHT_ORIENTATION_CAMERA, "CAMERA",  0, "Camera",  "Studio light is camera based"},
-               {STUDIOLIGHT_ORIENTATION_WORLD,  "WORLD",   0, "World",   "Studio light is world based"},
+               {0,                                  "UNKNOWN", 0,    "Unknown", "Studio light has no orientation"},
+               {STUDIOLIGHT_ORIENTATION_CAMERA,     "CAMERA",  0,    "Camera",  "Studio light is camera based"},
+               {STUDIOLIGHT_ORIENTATION_WORLD,      "WORLD",   0,    "World",   "Studio light is world based"},
+               {STUDIOLIGHT_ORIENTATION_VIEWNORMAL, "VIEWNORMAL", 0, "Matcap",  "Studio light is a matcap"},
                {0, NULL, 0, NULL, NULL}
        };
 
@@ -2284,6 +2540,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
        prop = RNA_def_property(srna, "light", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "shading.light");
        RNA_def_property_enum_items(prop, rna_enum_viewport_lighting_items);
+       RNA_def_property_enum_funcs(prop, "rna_View3DShading_light_get", "rna_View3DShading_light_set", "rna_View3DShading_light_itemf");
        RNA_def_property_ui_text(prop, "Lighting", "Lighting Method for Solid/Texture Viewport Shading");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
@@ -2300,6 +2557,13 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Studiolight", "Studio lighting setup");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
+       prop = RNA_def_property(srna, "matcap", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, rna_enum_matcap_items);
+       RNA_def_property_enum_default(prop, 0);
+       RNA_def_property_enum_funcs(prop, "rna_View3DShading_matcap_get", "rna_View3DShading_matcap_set", "rna_View3DShading_matcap_itemf");
+       RNA_def_property_ui_text(prop, "Matcap", "Matcap material and lighting");
+       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
        prop = RNA_def_property(srna, "studio_light_orientation", PROP_ENUM, PROP_NONE);
        RNA_define_verify_sdna(0);
        RNA_def_property_enum_sdna(prop, NULL, "shading.flag");
@@ -2588,34 +2852,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
                {0, NULL, 0, NULL, NULL}
        };
 
-       static const EnumPropertyItem view3d_matcap_items[] = {
-               {ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
-               {ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
-               {ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""},
-               {ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""},
-               {ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""},
-               {ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""},
-               {ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""},
-               {ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""},
-               {ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""},
-               {ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""},
-               {ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""},
-               {ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""},
-               {ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""},
-               {ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""},
-               {ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""},
-               {ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""},
-               {ICON_MATCAP_17, "17", ICON_MATCAP_17, "", ""},
-               {ICON_MATCAP_18, "18", ICON_MATCAP_18, "", ""},
-               {ICON_MATCAP_19, "19", ICON_MATCAP_19, "", ""},
-               {ICON_MATCAP_20, "20", ICON_MATCAP_20, "", ""},
-               {ICON_MATCAP_21, "21", ICON_MATCAP_21, "", ""},
-               {ICON_MATCAP_22, "22", ICON_MATCAP_22, "", ""},
-               {ICON_MATCAP_23, "23", ICON_MATCAP_23, "", ""},
-               {ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""},
-               {0, NULL, 0, NULL, NULL}
-       };
-
        srna = RNA_def_struct(brna, "SpaceView3D", "Space");
        RNA_def_struct_sdna(srna, "View3D");
        RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
@@ -2832,17 +3068,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Show 3D Marker Names", "Show names for reconstructed tracks objects");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
-       prop = RNA_def_property(srna, "use_matcap", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_MATCAP);
-       RNA_def_property_ui_text(prop, "Matcap", "Active Objects draw images mapped on normals, enhancing Solid Draw Mode");
-       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_enable");
-
-       prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "matcap_icon");
-       RNA_def_property_enum_items(prop, view3d_matcap_items);
-       RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture, active objects only");
-       RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
        prop = RNA_def_property(srna, "fx_settings", PROP_POINTER, PROP_NONE);
        RNA_def_property_ui_text(prop, "FX Options", "Options used for real time compositing");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);