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:
parent
52458ab49d
commit
2d720f51cd
Notes:
blender-bot
2023-02-14 07:31:32 +01:00
Referenced by issue #58117, Crash with keyframing
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue