diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-11-28 17:57:40 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-11-28 17:59:56 +0300 |
commit | 2d720f51cd786f3e0924602efb6ec89ef8ed077f (patch) | |
tree | 3b1ac1223a1c35e17e5085f99ef231273c801526 /source/blender | |
parent | 52458ab49d40081466e369709d68c13a6a47663e (diff) |
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.
Diffstat (limited to 'source/blender')
13 files changed, 250 insertions, 159 deletions
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", |