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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py4
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py11
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py13
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c11
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c16
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl57
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl33
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl146
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c61
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c3
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c3
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c37
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h13
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c19
16 files changed, 266 insertions, 171 deletions
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 5e57e267add..89c1f32ed2d 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -253,8 +253,8 @@ class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel):
layout.use_property_split = True
col = layout.column()
- col.prop(mat, "diffuse_color")
- col.prop(mat, "specular_color")
+ col.prop(mat, "diffuse_color", text="Color")
+ col.prop(mat, "metallic")
col.prop(mat, "roughness")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 6add7bf32eb..8ace0b8164e 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -1531,8 +1531,8 @@ class USERPREF_PT_studiolight_camera(Panel, StudioLightPanelMixin):
sl_orientation = 'CAMERA'
-class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin):
- bl_label = "Specular Lights"
+class USERPREF_PT_studiolight_lights(Panel, StudioLightPanelMixin):
+ bl_label = "Studio Lights"
sl_orientation = 'CAMERA'
@classmethod
@@ -1548,7 +1548,9 @@ class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin):
sub = col.column()
sub.active = light.use
+ sub.prop(light, "diffuse_color")
sub.prop(light, "specular_color")
+ sub.prop(light, "smooth")
col = split.column()
col.active = light.use
@@ -1561,6 +1563,8 @@ class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin):
userpref = context.user_preferences
system = userpref.system
+ layout.prop(system, "light_ambient")
+
light = system.solid_lights[0]
colsplit = column.split(factor=0.85)
self.opengl_light_buttons(colsplit, light)
@@ -1572,7 +1576,6 @@ class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin):
light = system.solid_lights[2]
self.opengl_light_buttons(column, light)
-
classes = (
USERPREF_HT_header,
USERPREF_PT_navigation,
@@ -1590,7 +1593,7 @@ classes = (
USERPREF_PT_studiolight_matcaps,
USERPREF_PT_studiolight_world,
USERPREF_PT_studiolight_camera,
- USERPREF_PT_studiolight_specular,
+ USERPREF_PT_studiolight_lights,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 77f9c2332ac..8eac3cec976 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -4205,13 +4205,14 @@ class VIEW3D_PT_shading_lighting(Panel):
sub.scale_y = 0.6 # smaller matcap/hdri preview
if shading.light == 'STUDIO':
- sub.template_icon_view(shading, "studio_light", scale=3)
+ # Not implemented right now
+ # sub.template_icon_view(shading, "studio_light", scale=3)
- if shading.selected_studio_light.orientation == 'WORLD':
- col.prop(shading, "studiolight_rotate_z", text="Rotation")
+ # if shading.selected_studio_light.orientation == 'WORLD':
+ # col.prop(shading, "studiolight_rotate_z", text="Rotation")
col = split.column()
- col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES')
+ # col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES')
elif shading.light == 'MATCAP':
sub.template_icon_view(shading, "studio_light", scale=3)
@@ -4355,8 +4356,8 @@ class VIEW3D_PT_shading_options(Panel):
sub.prop(shading, "object_outline_color", text="")
col = layout.column()
- if (shading.light is not 'MATCAP') and (shading.type is not 'WIREFRAME'):
- col.prop(shading, "show_specular_highlight")
+ if (shading.light == 'STUDIO') and (shading.type is not 'WIREFRAME'):
+ col.prop(shading, "show_specular_highlight", text="Specular Lighting")
class VIEW3D_PT_shading_options_shadow(Panel):
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f9f9905be3c..055e4b065a1 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -280,4 +280,15 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
}
}
+
+ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) {
+ for (ScrArea *sa = sc->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;
+ v3d->shading.flag |= V3D_SHADING_SPECULAR_HIGHLIGHT;
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index a65520c35fa..55c875e3412 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -421,6 +421,22 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
*/
{
/* (keep this block even if it becomes empty). */
+ copy_v4_fl4(userdef->light[0].vec, -0.580952, 0.228571, 0.781185, 0.0);
+ copy_v4_fl4(userdef->light[0].col, 0.900000, 0.900000, 0.900000, 1.000000);
+ copy_v4_fl4(userdef->light[0].spec, 0.318547, 0.318547, 0.318547, 1.000000);
+ userdef->light[0].smooth = 0.1;
+
+ copy_v4_fl4(userdef->light[1].vec, 0.788218, 0.593482, -0.162765, 0.0);
+ copy_v4_fl4(userdef->light[1].col, 0.267115, 0.269928, 0.358840, 1.000000);
+ copy_v4_fl4(userdef->light[1].spec, 0.090838, 0.090838, 0.090838, 1.000000);
+ userdef->light[1].smooth = 0.25;
+
+ copy_v4_fl4(userdef->light[2].vec, 0.696472, -0.696472, -0.172785, 0.0);
+ copy_v4_fl4(userdef->light[2].col, 0.293216, 0.304662, 0.401968, 1.000000);
+ copy_v4_fl4(userdef->light[2].spec, 0.069399, 0.020331, 0.020331, 1.000000);
+ userdef->light[2].smooth = 0.5;
+
+ copy_v4_fl4(userdef->light_ambient, 0.025000, 0.025000, 0.025000, 1.000000);
}
if (userdef->pixelsize == 0.0f)
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 3a538f4f2ac..fd058d45cf6 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
@@ -1,6 +1,7 @@
struct LightData {
- vec4 light_direction_vs;
+ vec4 direction;
vec4 specular_color;
+ vec4 diffuse_color_wrap; /* rgb: diffuse col a: wrapped lighting factor */
};
struct WorldData {
@@ -9,7 +10,8 @@ struct WorldData {
vec4 background_color_high;
vec4 object_outline_color;
vec4 shadow_direction_vs;
- LightData lights[3];
+ LightData lights[4];
+ vec4 ambient_color;
int num_lights;
int matcap_orientation;
float background_alpha;
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 f15e6b613a9..4aa471f70d8 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
@@ -1,6 +1,7 @@
out vec4 fragColor;
uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrixInverse;
uniform usampler2D objectId;
uniform sampler2D colorBuffer;
@@ -14,7 +15,6 @@ uniform vec4 viewvecs[3];
uniform float shadowMultiplier;
uniform float lightMultiplier;
uniform float shadowShift = 0.1;
-uniform mat3 normalWorldMatrix;
#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
uniform sampler2D matcapImage;
@@ -70,39 +70,30 @@ void main()
vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix);
-#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
- bool flipped = world_data.matcap_orientation != 0;
- vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped);
- diffuse_color = textureLod(matcapImage, matcap_uv, 0.0);
-#endif
-
-#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
- vec4 specular_data = texelFetch(specularBuffer, texel, 0);
- vec3 specular_color = get_world_specular_lights(world_data, specular_data, normal_viewport, I_vs);
-#else
- vec3 specular_color = vec3(0.0);
-#endif
-
+ /* -------- SHADING --------- */
#ifdef V3D_LIGHTING_FLAT
- vec3 diffuse_light = vec3(1.0);
-#endif
+ vec3 shaded_color = diffuse_color.rgb;
-#ifdef V3D_LIGHTING_MATCAP
- vec3 diffuse_light = texelFetch(specularBuffer, texel, 0).rgb;
-#endif
+#elif defined(V3D_LIGHTING_MATCAP)
+ bool flipped = world_data.matcap_orientation != 0;
+ vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped);
+ vec3 object_color = texelFetch(specularBuffer, texel, 0).rgb;
+ vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb;
+ vec3 shaded_color = matcap * object_color;
-#ifdef V3D_LIGHTING_STUDIO
-# ifdef STUDIOLIGHT_ORIENTATION_CAMERA
- vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
-# endif
+#elif defined(V3D_LIGHTING_STUDIO)
-# ifdef STUDIOLIGHT_ORIENTATION_WORLD
- vec3 normal_world = normalWorldMatrix * normal_viewport;
- vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
+# ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
+ vec4 specular_data = texelFetch(specularBuffer, texel, 0);
+# else
+ vec4 specular_data = vec4(0.0);
# endif
+ vec3 shaded_color = get_world_lighting(world_data,
+ diffuse_color.rgb, specular_data.rgb, specular_data.a,
+ normal_viewport, I_vs);
#endif
- vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
+ /* -------- POST EFFECTS --------- */
#ifdef V3D_SHADING_SSAO
vec2 cavity = texelFetch(cavityBuffer, texel, 0).rg;
shaded_color *= 1.0 - cavity.x;
@@ -119,16 +110,12 @@ void main()
/* The step function might be ok for meshes but it's
* clearly not the case for hairs. Do smoothstep in this case. */
float shadow_mix = smoothstep(1.0, shadowShift, light_factor);
- float light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix);
-
-#else /* V3D_SHADING_SHADOW */
- float light_multiplier = 1.0;
-#endif /* V3D_SHADING_SHADOW */
-
- shaded_color *= light_multiplier;
+ shaded_color *= mix(lightMultiplier, shadowMultiplier, shadow_mix);
+#endif
#ifdef V3D_SHADING_OBJECT_OUTLINE
shaded_color = mix(world_data.object_outline_color.rgb, shaded_color, object_outline);
-#endif /* V3D_SHADING_OBJECT_OUTLINE */
+#endif
+
fragColor = vec4(shaded_color, 1.0);
}
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 67a22073a4b..c00edb06100 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
@@ -4,7 +4,7 @@ uniform float ImageTransparencyCutoff = 0.1;
#endif
uniform mat4 ProjectionMatrix;
-uniform mat3 normalWorldMatrix;
+uniform mat4 ViewMatrixInverse;
uniform float alpha = 0.5;
uniform vec2 invertedViewportSize;
uniform vec4 viewvecs[3];
@@ -33,7 +33,6 @@ layout(location=1) out float revealageAccum; /* revealage actually stored in tra
void main()
{
vec4 diffuse_color;
- vec3 diffuse_light = vec3(1.0);
#ifdef V3D_SHADING_TEXTURE_COLOR
diffuse_color = texture(image, uv_interp);
@@ -51,30 +50,22 @@ void main()
vec3 nor = normalize(normal_viewport);
#endif
-#ifdef V3D_LIGHTING_MATCAP
+ /* -------- SHADING --------- */
+#ifdef V3D_LIGHTING_FLAT
+ vec3 shaded_color = diffuse_color.rgb;
+
+#elif defined(V3D_LIGHTING_MATCAP)
bool flipped = world_data.matcap_orientation != 0;
vec2 matcap_uv = matcap_uv_compute(I_vs, nor, flipped);
- diffuse_light = texture(matcapImage, matcap_uv).rgb;
-#endif
+ vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb;
+ vec3 shaded_color = matcap * diffuse_color.rgb;
-#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
- vec3 specular_color = get_world_specular_lights(world_data, vec4(materialSpecularColor.rgb, materialRoughness), nor, I_vs);
-#else
- vec3 specular_color = vec3(0.0);
+#elif defined(V3D_LIGHTING_STUDIO)
+ vec3 shaded_color = get_world_lighting(world_data,
+ diffuse_color.rgb, materialSpecularColor.rgb, materialRoughness,
+ nor, I_vs);
#endif
-#ifdef V3D_LIGHTING_STUDIO
-# ifdef STUDIOLIGHT_ORIENTATION_CAMERA
- diffuse_light = get_camera_diffuse_light(world_data, nor);
-# endif
-# ifdef STUDIOLIGHT_ORIENTATION_WORLD
- vec3 normal_world = normalWorldMatrix * nor;
- diffuse_light = get_world_diffuse_light(world_data, normal_world);
-# endif
-#endif
-
- vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
-
/* Based on :
* McGuire and Bavoil, Weighted Blended Order-Independent Transparency, Journal of
* Computer Graphics Techniques (JCGT), vol. 2, no. 2, 122–141, 2013
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 ab48aa5fa03..e25be733d44 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
@@ -72,58 +72,120 @@ vec3 spherical_harmonics(vec3 N, vec3 sh_coefs[STUDIOLIGHT_SH_MAX_COMPONENTS])
}
#endif
-vec3 get_world_diffuse_light(WorldData world_data, vec3 N)
+/* [Drobot2014a] Low Level Optimizations for GCN */
+vec4 fast_rcp(vec4 v)
{
- return spherical_harmonics(N, world_data.spherical_harmonics_coefs);
+ return intBitsToFloat(0x7eef370b - floatBitsToInt(v));
}
-vec3 get_camera_diffuse_light(WorldData world_data, vec3 N)
+vec3 brdf_approx(vec3 spec_color, float roughness, float NV)
{
- return spherical_harmonics(vec3(N.x, -N.z, N.y), world_data.spherical_harmonics_coefs);
+ /* Treat anything below 2% as shadowing.
+ * (in other words, makes it possible to completely disable
+ * specular on a material by setting specular color to black). */
+ float shadowing = clamp(50.0 * spec_color.g, 0.0, 1.0);
+ /* Very rough own approx. We don't need it to be correct, just fast.
+ * Just simulate fresnel effect with roughness attenuation. */
+ float fresnel = exp2(-8.35 * NV) * (1.0 - roughness);
+ return mix(spec_color, vec3(1.0), fresnel) * shadowing;
}
-/* N And I are in View Space. */
-vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N, vec3 I)
+void prep_specular(
+ vec3 L, vec3 I, vec3 N, vec3 R,
+ out float NL, out float wrapped_NL, out float spec_angle)
{
-#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
- vec3 specular_light = specular_data.rgb * light_data.specular_color.rgb * light_data.specular_color.a;
-
- float shininess = exp2(10.0 * (1.0 - specular_data.a) + 1);
-
-# ifdef BLINN
- float normalization_factor = (shininess + 8.0) / (8.0 * M_PI);
- vec3 L = -light_data.light_direction_vs.xyz;
- vec3 halfDir = normalize(L + I);
- float spec_angle = max(dot(halfDir, N), 0.0);
- float NL = max(dot(L, N), 0.0);
- float specular_influence = pow(spec_angle, shininess) * NL * normalization_factor;
-
-# else
- vec3 reflection_vector = reflect(I, N);
- float spec_angle = max(dot(light_data.light_direction_vs.xyz, reflection_vector), 0.0);
- float specular_influence = pow(spec_angle, shininess);
-# endif
+ wrapped_NL = dot(L, R);
+ vec3 half_dir = normalize(L + I);
+ spec_angle = clamp(dot(half_dir, N), 0.0, 1.0);
+ NL = clamp(dot(L, N), 0.0, 1.0);
+}
- vec3 specular_color = specular_light * specular_influence;
+/* Normalized Blinn shading */
+vec4 blinn_specular(vec4 shininess, vec4 spec_angle, vec4 NL)
+{
+ /* Pi is already divided in the lamp power.
+ * normalization_factor = (shininess + 8.0) / (8.0 * M_PI) */
+ vec4 normalization_factor = shininess * 0.125 + 1.0;
+ vec4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor;
-#else /* V3D_SHADING_SPECULAR_HIGHLIGHT */
- vec3 specular_color = vec3(0.0);
-#endif /* V3D_SHADING_SPECULAR_HIGHLIGHT */
- return specular_color;
+ return spec_light;
}
-vec3 get_world_specular_lights(WorldData world_data, vec4 specular_data, vec3 N, vec3 I)
+/* NL need to be unclamped. w in [0..1] range. */
+vec4 wrapped_lighting(vec4 NL, vec4 w)
{
- vec3 specular_light = vec3(0.0);
- /* Manual loop unrolling provide much better perf. */
- if (world_data.num_lights > 0) {
- specular_light += get_world_specular_light(specular_data, world_data.lights[0], N, I);
- }
- if (world_data.num_lights > 1) {
- specular_light += get_world_specular_light(specular_data, world_data.lights[1], N, I);
- }
- if (world_data.num_lights > 2) {
- specular_light += get_world_specular_light(specular_data, world_data.lights[2], N, I);
- }
- return specular_light;
+ vec4 w_1 = w + 1.0;
+ vec4 denom = fast_rcp(w_1 * w_1);
+ return clamp((NL + w) * denom, 0.0, 1.0);
+}
+
+vec3 get_world_lighting(
+ WorldData world_data,
+ vec3 diffuse_color, vec3 specular_color, float roughness,
+ vec3 N, vec3 I)
+{
+ vec3 specular_light = world_data.ambient_color.rgb;
+ vec3 diffuse_light = world_data.ambient_color.rgb;
+ vec4 wrap = vec4(
+ world_data.lights[0].diffuse_color_wrap.a,
+ world_data.lights[1].diffuse_color_wrap.a,
+ world_data.lights[2].diffuse_color_wrap.a,
+ world_data.lights[3].diffuse_color_wrap.a
+ );
+
+#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
+ /* Prepare Specular computation. Eval 4 lights at once. */
+ vec3 R = -reflect(I, N);
+ vec4 spec_angle, spec_NL, wrap_NL;
+ prep_specular(world_data.lights[0].direction.xyz, I, N, R, spec_NL.x, wrap_NL.x, spec_angle.x);
+ prep_specular(world_data.lights[1].direction.xyz, I, N, R, spec_NL.y, wrap_NL.y, spec_angle.y);
+ prep_specular(world_data.lights[2].direction.xyz, I, N, R, spec_NL.z, wrap_NL.z, spec_angle.z);
+ prep_specular(world_data.lights[3].direction.xyz, I, N, R, spec_NL.w, wrap_NL.w, spec_angle.w);
+
+ vec4 gloss = vec4(1.0 - roughness);
+ /* Reduce gloss for smooth light. (simulate bigger light) */
+ gloss *= 1.0 - wrap;
+ vec4 shininess = exp2(10.0 * gloss + 1.0);
+
+ vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL);
+
+ /* Simulate Env. light. */
+ vec4 w = mix(wrap, vec4(1.0), roughness);
+ vec4 spec_env = wrapped_lighting(wrap_NL, w);
+
+ spec_light = mix(spec_light, spec_env, wrap * wrap);
+
+ /* Multiply result by lights specular colors. */
+ specular_light += spec_light.x * world_data.lights[0].specular_color.rgb;
+ specular_light += spec_light.y * world_data.lights[1].specular_color.rgb;
+ specular_light += spec_light.z * world_data.lights[2].specular_color.rgb;
+ specular_light += spec_light.w * world_data.lights[3].specular_color.rgb;
+
+ float NV = clamp(dot(N, I), 0.0, 1.0);
+ specular_color = brdf_approx(specular_color, roughness, NV);
+#endif
+ specular_light *= specular_color;
+
+ /* Prepare diffuse computation. Eval 4 lights at once. */
+ vec4 diff_NL;
+ diff_NL.x = dot(world_data.lights[0].direction.xyz, N);
+ diff_NL.y = dot(world_data.lights[1].direction.xyz, N);
+ diff_NL.z = dot(world_data.lights[2].direction.xyz, N);
+ diff_NL.w = dot(world_data.lights[3].direction.xyz, N);
+
+ vec4 diff_light = wrapped_lighting(diff_NL, wrap);
+
+ /* Multiply result by lights diffuse colors. */
+ diffuse_light += diff_light.x * world_data.lights[0].diffuse_color_wrap.rgb;
+ diffuse_light += diff_light.y * world_data.lights[1].diffuse_color_wrap.rgb;
+ diffuse_light += diff_light.z * world_data.lights[2].diffuse_color_wrap.rgb;
+ diffuse_light += diff_light.w * world_data.lights[3].diffuse_color_wrap.rgb;
+
+ /* Energy conservation with colored specular look strange.
+ * Limit this strangeness by using mono-chromatic specular intensity. */
+ float spec_energy = dot(specular_color, vec3(0.33333));
+
+ diffuse_light *= diffuse_color * (1.0 - spec_energy);
+
+ return diffuse_light + specular_light;
}
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 18f4ced6074..522b7d6e8c4 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -157,37 +157,56 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
WORKBENCH_UBO_World *wd = &wpd->world_data;
- float view_matrix[4][4];
+ float view_matrix[4][4], view_inv[4][4], rot_matrix[4][4];
DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(view_inv, DRW_MAT_VIEWINV);
copy_v3_v3(r_light_direction, scene->display.light_direction);
negate_v3(r_light_direction);
- {
- WORKBENCH_UBO_Light *light = &wd->lights[0];
- mul_v3_mat3_m4v3(light->light_direction_vs, view_matrix, r_light_direction);
- light->light_direction_vs[3] = 0.0f;
- copy_v3_fl(light->specular_color, 1.0f);
- light->energy = 1.0f;
- copy_v4_v4(wd->shadow_direction_vs, light->light_direction_vs);
- wd->num_lights = 1;
+ /* Shadow direction. */
+ mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, r_light_direction);
+
+ /* TODO enable when we support studiolight presets. */
+ if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) && false) {
+ axis_angle_to_mat4_single(rot_matrix, 'Y', -wpd->shading.studiolight_rot_z);
+ mul_m4_m4m4(rot_matrix, rot_matrix, view_matrix);
+ swap_v3_v3(rot_matrix[2], rot_matrix[1]);
+ negate_v3(rot_matrix[2]);
+ }
+ else {
+ unit_m4(rot_matrix);
}
- if (!STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
- int light_index = 0;
- for (int index = 0 ; index < 3; index++) {
- SolidLight *sl = &U.light[index];
- if (sl->flag) {
- WORKBENCH_UBO_Light *light = &wd->lights[light_index++];
- copy_v4_v4(light->light_direction_vs, sl->vec);
- negate_v3(light->light_direction_vs);
- copy_v4_v4(light->specular_color, sl->spec);
- light->energy = 1.0f;
- }
+ /* Studio Lights. */
+ for (int i = 0; i < 4; i++) {
+ WORKBENCH_UBO_Light *light = &wd->lights[i];
+ /* TODO use 4 lights in studiolights prefs. */
+ if (i > 2) {
+ copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
+ copy_v3_fl(light->specular_color, 0.0f);
+ copy_v3_fl(light->diffuse_color, 0.0f);
+ continue;
+ }
+
+ SolidLight *sl = &U.light[i];
+ if (sl->flag) {
+ copy_v3_v3(light->light_direction, sl->vec);
+ mul_mat3_m4_v3(rot_matrix, light->light_direction);
+ /* We should predivide the power by PI but that makes the lights really dim. */
+ copy_v3_v3(light->specular_color, sl->spec);
+ copy_v3_v3(light->diffuse_color, sl->col);
+ light->wrapped = sl->smooth;
+ }
+ else {
+ copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
+ copy_v3_fl(light->specular_color, 0.0f);
+ copy_v3_fl(light->diffuse_color, 0.0f);
}
- wd->num_lights = light_index;
}
+ copy_v4_v4(wd->ambient_color, U.light_ambient);
+
DRW_uniformbuffer_update(wpd->world_ubo, wd);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index fa50a7a2232..5c65cf78820 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -78,7 +78,6 @@ static struct {
SceneDisplay display; /* world light direction for shadows */
int next_object_id;
- float normal_world_matrix[3][3];
struct GPUUniformBuffer *sampling_ubo;
struct GPUTexture *jitter_tx;
@@ -517,8 +516,6 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
}
-
- workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
}
void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 22b2a4020af..4365f4ec27c 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -62,7 +62,6 @@ static struct {
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
int next_object_id;
- float normal_world_matrix[3][3];
} e_data = {{NULL}};
/* Shaders */
@@ -168,7 +167,6 @@ static WORKBENCH_MaterialData *get_or_create_material_data(
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_float(grp, "alpha", &wpd->shading.xray_alpha, 1);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
workbench_material_copy(material, &material_template);
if (STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)) {
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
@@ -445,7 +443,6 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
ob, psys, md,
psl->transparent_accum_pass,
shader);
- workbench_material_set_normal_world_matrix(shgrp, wpd, e_data.normal_world_matrix);
DRW_shgroup_uniform_block(shgrp, "world_block", wpd->world_ubo);
workbench_material_shgroup_uniform(wpd, shgrp, material, ob);
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 6f43e1f8707..cf0ed3147d0 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -8,17 +8,15 @@
#include "BLI_hash.h"
#define HSV_SATURATION 0.5
-#define HSV_VALUE 0.9
+#define HSV_VALUE 0.8
void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data)
{
/* When V3D_SHADING_TEXTURE_COLOR is active, use V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */
int color_type = wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR ? V3D_SHADING_MATERIAL_COLOR : wpd->shading.color_type;
- static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
- static float default_specular_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
- copy_v4_v4(data->diffuse_color, default_diffuse_color);
- copy_v4_v4(data->specular_color, default_specular_color);
- data->roughness = 0.5f;
+ copy_v4_fl4(data->diffuse_color, 0.8f, 0.8f, 0.8f, 1.0f);
+ copy_v4_fl4(data->specular_color, 0.05f, 0.05f, 0.05f, 1.0f); /* Dielectric: 5% reflective. */
+ data->roughness = 0.5; /* sqrtf(0.25f); */
if (color_type == V3D_SHADING_SINGLE_COLOR) {
copy_v3_v3(data->diffuse_color, wpd->shading.single_color);
@@ -36,9 +34,15 @@ void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Mate
else {
/* V3D_SHADING_MATERIAL_COLOR */
if (mat) {
- copy_v3_v3(data->diffuse_color, &mat->r);
- copy_v3_v3(data->specular_color, &mat->specr);
- data->roughness = mat->roughness;
+ if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
+ mul_v3_v3fl(data->diffuse_color, &mat->r, 1.0f - mat->metallic);
+ mul_v3_v3fl(data->specular_color, &mat->r, mat->metallic);
+ add_v3_fl(data->specular_color, 0.05f * (1.0f - mat->metallic));
+ data->roughness = sqrtf(mat->roughness); /* Remap to disney roughness. */
+ }
+ else {
+ copy_v3_v3(data->diffuse_color, &mat->r);
+ }
}
}
}
@@ -161,21 +165,6 @@ int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_tex
return index;
}
-void workbench_material_set_normal_world_matrix(
- DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
-{
- if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
- float view_matrix_inverse[4][4];
- float rot_matrix[4][4];
- float matrix[4][4];
- axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
- DRW_viewport_matrix_get(view_matrix_inverse, DRW_MAT_VIEWINV);
- mul_m4_m4m4(matrix, rot_matrix, view_matrix_inverse);
- copy_m3_m4(persistent_matrix, matrix);
- DRW_shgroup_uniform_mat3(grp, "normalWorldMatrix", persistent_matrix);
- }
-}
-
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob)
{
int color_type = wpd->shading.color_type;
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 97da3e5b58d..74764a1b159 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -59,7 +59,7 @@
(IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || \
((IS_NAVIGATING(wpd) || wpd->is_playback) && (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8))))
#define TAA_ENABLED(wpd) (DRW_state_is_image_render() || (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd) && !wpd->is_playback))
-#define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)))
+#define SPECULAR_HIGHLIGHT_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)))
#define OBJECT_OUTLINE_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
#define OBJECT_ID_PASS_ENABLED(wpd) (OBJECT_OUTLINE_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
@@ -135,9 +135,9 @@ typedef struct WORKBENCH_Data {
} WORKBENCH_Data;
typedef struct WORKBENCH_UBO_Light {
- float light_direction_vs[4];
- float specular_color[3];
- float energy;
+ float light_direction[4];
+ float specular_color[3], pad;
+ float diffuse_color[3], wrapped;
} WORKBENCH_UBO_Light;
#define WORKBENCH_SH_DATA_LEN ((STUDIOLIGHT_SH_BANDS == 2) ? 6 : STUDIOLIGHT_SH_EFFECTIVE_COEFS_LEN)
@@ -148,7 +148,8 @@ typedef struct WORKBENCH_UBO_World {
float background_color_high[4];
float object_outline_color[4];
float shadow_direction_vs[4];
- WORKBENCH_UBO_Light lights[3];
+ WORKBENCH_UBO_Light lights[4];
+ float ambient_color[4];
int num_lights;
int matcap_orientation;
float background_alpha;
@@ -293,8 +294,6 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data);
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost);
int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
-void workbench_material_set_normal_world_matrix(
- DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3]);
void workbench_material_shgroup_uniform(
WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob);
void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material);
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 952c4dcd831..5bb3523a458 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -492,7 +492,8 @@ enum {
};
typedef struct SolidLight {
- int flag, pad;
+ int flag;
+ float smooth;
float col[4], spec[4], vec[4];
} SolidLight;
@@ -586,6 +587,7 @@ typedef struct UserDef {
short gp_settings; /* eGP_UserdefSettings */
short tb_leftmouse, tb_rightmouse;
struct SolidLight light[3];
+ float light_ambient[3], pad7;
short gizmo_flag, gizmo_size;
short pad6[3];
short textimeout, texcollectrate;
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 921d8a3b65d..3610a9b8514 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3478,6 +3478,13 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Enabled", "Enable this OpenGL light in solid draw mode");
RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
+ prop = RNA_def_property(srna, "smooth", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "smooth");
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Smooth", "Smooth the lighting from this light");
+ RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
+
prop = RNA_def_property(srna, "direction", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_float_sdna(prop, NULL, "vec");
RNA_def_property_array(prop, 3);
@@ -3490,6 +3497,12 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Specular Color", "Color of the light's specular highlight");
RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
+
+ prop = RNA_def_property(srna, "diffuse_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "col");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Diffuse Color", "Color of the light's diffuse highlight");
+ RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
}
static void rna_def_userdef_walk_navigation(BlenderRNA *brna)
@@ -4278,6 +4291,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "UserSolidLight");
RNA_def_property_ui_text(prop, "Solid Lights", "Lights user to display objects in solid draw mode");
+ prop = RNA_def_property(srna, "light_ambient", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "light_ambient");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Ambient Color", "Color of the ambient light that uniformly lit the scene");
+ RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
+
prop = RNA_def_property(srna, "use_weight_color_range", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_CUSTOM_RANGE);
RNA_def_property_ui_text(prop, "Use Weight Color Range",