Workbench: Change Studio lighting

This is in order to have more flexible ligthing presets in the future.
The diffuse lighting from hdris was nice but lacked the corresponding
specular information. This is an attempt to make it possible to customize
the lighting and have a cheap/easy/nice-looking pseudo-PBR workflow.

* Add cheap PBR to Workbench with fresnel and better roughness support.
  This improves the look of the metallic surfaces and is easier to control.
* Add ambient light to studio lights settings: just a constant color added
  to the shading.
* Add Smooth option to studio lights settings: This option fakes the
  effect of making the light bigger making the lighting smoother for this
  light. Smoother lights gets reflected like a background hdri.
* Change default light settings to include the smooth params.
* Remove specular highlights from flat shading. (could be added back but
  how do we make it good looking?)
* If specular lighting is disabled, use base color without using metallic.
* Include a lot of code simplification/cleanup/confusion fix.
This commit is contained in:
Clément Foucault 2018-11-28 15:57:40 +01:00
parent 52458ab49d
commit 2d720f51cd
Notes: blender-bot 2023-02-14 07:31:32 +01:00
Referenced by issue #58117, Crash with keyframing
16 changed files with 265 additions and 170 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
/* -------- 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, normal_viewport, flipped);
diffuse_color = textureLod(matcapImage, matcap_uv, 0.0);
#endif
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_SHADING_SPECULAR_HIGHLIGHT
#elif defined(V3D_LIGHTING_STUDIO)
# 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
#ifdef V3D_LIGHTING_FLAT
vec3 diffuse_light = vec3(1.0);
#endif
#ifdef V3D_LIGHTING_MATCAP
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);
# 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);
}

View File

@ -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, 122141, 2013

View File

@ -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)
{
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);
}
/* 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;
return spec_light;
}
/* NL need to be unclamped. w in [0..1] range. */
vec4 wrapped_lighting(vec4 NL, vec4 w)
{
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
vec3 specular_light = specular_data.rgb * light_data.specular_color.rgb * light_data.specular_color.a;
/* 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);
float shininess = exp2(10.0 * (1.0 - specular_data.a) + 1);
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);
# 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;
vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL);
# 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
/* Simulate Env. light. */
vec4 w = mix(wrap, vec4(1.0), roughness);
vec4 spec_env = wrapped_lighting(wrap_NL, w);
vec3 specular_color = specular_light * specular_influence;
spec_light = mix(spec_light, spec_env, wrap * wrap);
#else /* V3D_SHADING_SPECULAR_HIGHLIGHT */
vec3 specular_color = vec3(0.0);
#endif /* V3D_SHADING_SPECULAR_HIGHLIGHT */
return specular_color;
}
vec3 get_world_specular_lights(WorldData world_data, vec4 specular_data, vec3 N, vec3 I)
{
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;
/* 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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",