diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-05-30 15:40:57 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-05-30 15:42:07 +0300 |
commit | acaf46db0ea7103aaa3f46092b3582611d37ca0f (patch) | |
tree | bfd0adacdbbb6852c49cbf9b3ac73503e62bb638 /source/blender/draw | |
parent | 29f9a197088e0e1ea56cae675803f61165d790c1 (diff) |
Workbench: Specular Highlights
Added specular highlights for:
- Solid studio shading
- Texture studio shading
Diffstat (limited to 'source/blender/draw')
10 files changed, 73 insertions, 27 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 9bd240afe3a..0889ce9a334 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -149,7 +149,7 @@ static void eevee_cache_populate(void *vedata, Object *ob) } } else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) { - /* do not add any light sources to the cache */ + /* do not add any scene light sources to the cache */ } else if (ob->type == OB_LIGHTPROBE) { if ((ob->base_flag & BASE_FROMDUPLI) != 0) { 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 d0b1c580e5f..c826a5b82fa 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -8,4 +8,6 @@ struct WorldData { vec4 background_color_low; vec4 background_color_high; vec4 object_outline_color; + vec4 light_direction_vs; + float specular_sharpness; }; 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 35867a566f1..525b934d3be 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 @@ -10,7 +10,6 @@ uniform float lightMultiplier; uniform float shadowShift = 0.1; uniform mat3 normalWorldMatrix; -uniform vec3 lightDirection; /* light direction in view space */ layout(std140) uniform world_block { WorldData world_data; @@ -57,14 +56,17 @@ void main() #ifdef V3D_LIGHTING_STUDIO -#ifdef STUDIOLIGHT_ORIENTATION_CAMERA + #ifdef STUDIOLIGHT_ORIENTATION_CAMERA vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport); -#endif -#ifdef STUDIOLIGHT_ORIENTATION_WORLD + #endif + + #ifdef STUDIOLIGHT_ORIENTATION_WORLD vec3 normal_world = normalWorldMatrix * normal_viewport; vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); -#endif - vec3 shaded_color = diffuse_light * diffuse_color.rgb; + #endif + + vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); + vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color; #else /* V3D_LIGHTING_STUDIO */ vec3 shaded_color = diffuse_color.rgb; @@ -72,7 +74,7 @@ void main() #endif /* V3D_LIGHTING_STUDIO */ #ifdef V3D_SHADING_SHADOW - float shadow_mix = step(-shadowShift, dot(normal_viewport, lightDirection)); + float shadow_mix = step(-shadowShift, dot(normal_viewport, world_data.light_direction_vs.xyz)); float light_multiplier; light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix); 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 309ae063284..6585bac9289 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 @@ -36,7 +36,9 @@ void main() vec3 normal_world = normalWorldMatrix * normal_viewport; vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); #endif - vec3 shaded_color = diffuse_light * diffuse_color.rgb; + + vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); + vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color; #else /* V3D_LIGHTING_STUDIO */ vec3 shaded_color = diffuse_color.rgb; 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 6507f1ec707..7e476080b64 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 @@ -18,3 +18,19 @@ vec3 get_camera_diffuse_light(WorldData world_data, vec3 N) result = mix(result, world_data.diffuse_light_y_neg, clamp(-N.z, 0.0, 1.0)); return result.xyz; } + +/* N And I are in View Space. */ +vec3 get_world_specular_light(WorldData world_data, vec3 N, vec3 I) +{ +#ifdef V3D_SHADING_SPECULAR_HIGHLIGHTS + vec3 reflection_vector = reflect(I, N); + vec3 specular_light = vec3(1.0); + /* Simple frontal specular highlights. */ + float specular_influence = pow(max(0.0, dot(world_data.light_direction_vs.xyz, reflection_vector)), world_data.specular_sharpness); + vec3 specular_color = specular_light * specular_influence; + +#else /* V3D_SHADING_SPECULAR_HIGHLIGHTS */ + vec3 specular_color = vec3(0.0); +#endif /* V3D_SHADING_SPECULAR_HIGHLIGHTS */ + return specular_color; +} diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index bbd8c57a5b9..062a5b04988 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -5,6 +5,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) { const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; wpd->material_hash = BLI_ghash_ptr_new(__func__); View3D *v3d = draw_ctx->v3d; @@ -36,10 +37,38 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color); wd->object_outline_color[3] = 1.0f; + wd->specular_sharpness = 100 - sqrtf(scene->display.roughness)* 100; wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data); } +void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3]) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + +#if 0 + if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { + BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED); + float rot_matrix[3][3]; + axis_angle_to_mat3_single(rot_matrix, 'Z', wpd->shading.studiolight_rot_z); + mul_v3_m3v3(e_data.display.light_direction, rot_matrix, wpd->studio_light->light_direction); + } + else { +#else + { +#endif + copy_v3_v3(light_direction, scene->display.light_direction); + negate_v3(light_direction); + } + + float view_matrix[4][4]; + DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); + mul_v3_mat3_m4v3(wpd->world_data.light_direction_vs, view_matrix, light_direction); + wpd->world_data.light_direction_vs[3] = 0.0; + DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data); +} + void workbench_private_data_free(WORKBENCH_PrivateData *wpd) { BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 6a96822984d..f0494325475 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -304,22 +304,10 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) select_deferred_shaders(wpd); /* Deferred Mix Pass */ { - copy_v3_v3(e_data.display.light_direction, scene->display.light_direction); - negate_v3(e_data.display.light_direction); -#if 0 - if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { - BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED); - float rot_matrix[3][3]; - // float dir[3] = {0.57, 0.57, -0.57}; - axis_angle_to_mat3_single(rot_matrix, 'Z', wpd->shading.studiolight_rot_z); - mul_v3_m3v3(e_data.display.light_direction, rot_matrix, wpd->studio_light->light_direction); - } -#endif - float view_matrix[4][4]; - DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); - mul_v3_mat3_m4v3(e_data.light_direction_vs, view_matrix, e_data.display.light_direction); + workbench_private_data_get_light_direction(wpd, e_data.display.light_direction); e_data.display.shadow_shift = scene->display.shadow_shift; + copy_v3_v3(e_data.light_direction_vs, wpd->world_data.light_direction_vs); if (SHADOW_ENABLED(wpd)) { psl->composite_pass = DRW_pass_create( @@ -327,7 +315,6 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass); workbench_composite_uniforms(wpd, grp); DRW_shgroup_stencil_mask(grp, 0x00); - DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction_vs, 1); DRW_shgroup_uniform_float(grp, "lightMultiplier", &light_multiplier, 1); DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1); DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1); @@ -368,7 +355,6 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass); DRW_shgroup_stencil_mask(grp, 0x00); workbench_composite_uniforms(wpd, grp); - DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction_vs, 1); DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->shadow_multiplier, 1); DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1); DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1); diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index d2c262bc4ac..4ba6ee3fdc9 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -252,6 +252,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) } WORKBENCH_PrivateData *wpd = stl->g_data; workbench_private_data_init(wpd); + float light_direction[3]; + workbench_private_data_get_light_direction(wpd, light_direction); if (!e_data.next_object_id) { e_data.next_object_id = 1; diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 6028d3816d4..2dffafbe409 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -52,6 +52,9 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype) if (wpd->shading.flag & V3D_SHADING_SHADOW) { BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n"); } + if (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHTS) { + BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHTS\n"); + } if (wpd->shading.light & V3D_LIGHTING_STUDIO) { BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_STUDIO\n"); if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { @@ -107,7 +110,7 @@ uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template) int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype) { - const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW; + const int DRAWOPTIONS_MASK = V3D_SHADING_OBJECT_OUTLINE | V3D_SHADING_SHADOW | V3D_SHADING_SPECULAR_HIGHLIGHTS; int index = (wpd->shading.flag & DRAWOPTIONS_MASK); index = (index << 2) + wpd->shading.light; index = (index << 2); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index bffac99c6d7..918715581d9 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -37,7 +37,7 @@ #define WORKBENCH_ENGINE "BLENDER_WORKBENCH" #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895 -#define MAX_SHADERS 255 +#define MAX_SHADERS 512 #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) @@ -106,6 +106,9 @@ typedef struct WORKBENCH_UBO_World { float background_color_low[4]; float background_color_high[4]; float object_outline_color[4]; + float light_direction_vs[4]; + float specular_sharpness; + float pad[3]; } WORKBENCH_UBO_World; BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16) @@ -209,6 +212,7 @@ bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, /* workbench_data.c */ void workbench_private_data_init(WORKBENCH_PrivateData *wpd); void workbench_private_data_free(WORKBENCH_PrivateData *wpd); +void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3]); extern DrawEngineType draw_engine_workbench_solid; extern DrawEngineType draw_engine_workbench_transparent; |