diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-05 09:15:30 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-05 12:38:33 +0300 |
commit | a3815f87773c7d45740c98c888718424d736870b (patch) | |
tree | 4cd46cb327fe76e1dfcde04dcdd99d1cc4a2e9b5 /source | |
parent | ade710500df4f333077daa96e3ab72eb2cdc3b94 (diff) |
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.
Diffstat (limited to 'source')
15 files changed, 523 insertions, 174 deletions
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index 2f2e948ab26..9bf9f0ea904 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -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); diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 4ef7b3d2247..0d44509ae65 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -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)) { diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 144b3889d30..7827e793049 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -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); + } + } + } + } + } + } } } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl index fc076ee8117..8d648ce7d7b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -23,4 +23,5 @@ struct MaterialData { vec4 diffuse_color; vec4 specular_color; float roughness; + int matcap_texture_index; }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl index 5f37490603d..326837bc69f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl @@ -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 diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index a9c84e11aa6..e04bffdeea5 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -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); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index bc7741f853c..5931a11f184 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -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); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index be124257c33..6f4237ebd0a 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -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; diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 4ee12a692f5..4eca3acf238 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -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]; diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index ba5ab7f1cc3..285551abb12 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -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); } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 3ed0c207bec..931ffc61810 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -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: { diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 7c9c7b96b7b..2e2e6f8127a 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -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; } diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 00cb6666430..ac85f4c5296 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -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) diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index be980b4fead..68da501d452 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index b36014370f6..46a27ff5d6c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -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); |