Workbench: Matcaps T55291

- 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.
This commit is contained in:
Jeroen Bakker 2018-06-05 08:15:30 +02:00
parent ade710500d
commit a3815f8777
41 changed files with 538 additions and 183 deletions

@ -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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@ -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()

@ -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);

@ -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)) {

@ -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);
}
}
}
}
}
}
}
}

@ -23,4 +23,5 @@ struct MaterialData {
vec4 diffuse_color;
vec4 specular_color;
float roughness;
int matcap_texture_index;
};

@ -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_STUDIO
#ifdef STUDIOLIGHT_ORIENTATION_CAMERA
vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
#endif
#ifdef V3D_LIGHTING_FLAT
vec3 diffuse_light = vec3(1.0);
#endif
#ifdef STUDIOLIGHT_ORIENTATION_WORLD
#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
vec3 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);
#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

@ -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);
}

@ -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);

@ -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;

@ -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];

@ -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);
}

@ -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:
{

@ -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;
}

@ -38,17 +38,22 @@
#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)

@ -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 */

@ -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);