[Bf-blender-cvs] [76a7ea0b713] tmp-workbench-rewrite: Workbench: Refactor: Add matcap support

Clément Foucault noreply at git.blender.org
Tue Mar 3 17:35:51 CET 2020


Commit: 76a7ea0b7137b08ec12fa5181d448865e4440f00
Author: Clément Foucault
Date:   Sat Feb 29 18:09:07 2020 +0100
Branches: tmp-workbench-rewrite
https://developer.blender.org/rB76a7ea0b7137b08ec12fa5181d448865e4440f00

Workbench: Refactor: Add matcap support

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
A	source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl
M	source/blender/draw/engines/workbench/workbench_opaque.c
M	source/blender/draw/engines/workbench/workbench_shader.c

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 6478bc46333..c876dd4136a 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -263,6 +263,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC
 data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_ghost_resolve_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_image_lib.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_matcap_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_material_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_curvature_lib.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index 4af03d8b82e..5131b9dae06 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -122,17 +122,3 @@ vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
     return vec3(0.0, 0.0, 1.0);
   }
 }
-
-vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped)
-{
-  /* Quick creation of an orthonormal basis */
-  float a = 1.0 / (1.0 + I.z);
-  float b = -I.x * I.y * a;
-  vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x);
-  vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y);
-  vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N));
-  if (flipped) {
-    matcap_uv.x = -matcap_uv.x;
-  }
-  return matcap_uv * 0.496 + 0.5;
-}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
index 19f6ce5f14c..915a1596180 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
@@ -1,6 +1,7 @@
 
 #pragma BLENDER_REQUIRE(common_view_lib.glsl)
 #pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_matcap_lib.glsl)
 #pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl)
 
 uniform sampler2D materialBuffer;
@@ -12,25 +13,25 @@ out vec4 fragColor;
 
 void main()
 {
+  /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
+  vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix);
   vec3 normal = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st));
   vec4 mat_data = texture(materialBuffer, uvcoordsvar.st);
 
-  vec3 I_vs = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix);
-
   vec3 base_color = mat_data.rgb;
 
   float roughness, metallic;
   workbench_float_pair_decode(mat_data.a, roughness, metallic);
 
-  vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic);
-  vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic);
-
 #ifdef V3D_LIGHTING_MATCAP
-  fragColor.rgb = vec3(1.0);
+  /* When using matcaps, mat_data.a is the backface sign. */
+  normal = (mat_data.a > 0.0) ? normal : -normal;
+
+  fragColor.rgb = get_matcap_lighting(base_color, normal, I);
 #endif
 
 #ifdef V3D_LIGHTING_STUDIO
-  fragColor.rgb = get_world_lighting(diffuse_color, specular_color, roughness, normal, I_vs);
+  fragColor.rgb = get_world_lighting(base_color, roughness, metallic, normal, I);
 #endif
 
 #ifdef V3D_LIGHTING_FLAT
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl
new file mode 100644
index 00000000000..3aa37f1971d
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl
@@ -0,0 +1,32 @@
+
+#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
+
+vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped)
+{
+  /* Quick creation of an orthonormal basis */
+  float a = 1.0 / (1.0 + I.z);
+  float b = -I.x * I.y * a;
+  vec3 b1 = vec3(1.0 - I.x * I.x * a, b, -I.x);
+  vec3 b2 = vec3(b, 1.0 - I.y * I.y * a, -I.y);
+  vec2 matcap_uv = vec2(dot(b1, N), dot(b2, N));
+  if (flipped) {
+    matcap_uv.x = -matcap_uv.x;
+  }
+  return matcap_uv * 0.496 + 0.5;
+}
+
+uniform sampler2D matcapDiffuseImage;
+uniform sampler2D matcapSpecularImage;
+
+uniform bool useSpecular = false;
+
+vec3 get_matcap_lighting(vec3 base_color, vec3 N, vec3 I)
+{
+  bool flipped = world_data.matcap_orientation != 0;
+  vec2 uv = matcap_uv_compute(I, N, flipped);
+
+  vec3 diffuse = textureLod(matcapDiffuseImage, uv, 0.0).rgb;
+  vec3 specular = textureLod(matcapSpecularImage, uv, 0.0).rgb;
+
+  return diffuse * base_color + specular * float(useSpecular);
+}
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 58e8370537a..61e4bc06411 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
@@ -43,8 +43,11 @@ vec4 wrapped_lighting(vec4 NL, vec4 w)
   return clamp((NL + w) * denom, 0.0, 1.0);
 }
 
-vec3 get_world_lighting(vec3 diffuse_color, vec3 specular_color, float roughness, vec3 N, vec3 I)
+vec3 get_world_lighting(vec3 base_color, float roughness, float metallic, vec3 N, vec3 I)
 {
+  vec3 specular_color = mix(vec3(0.05), base_color.rgb, metallic);
+  vec3 diffuse_color = mix(base_color.rgb, vec3(0.0), metallic);
+
   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,
diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c
index 07692abebcb..0a2a7733e56 100644
--- a/source/blender/draw/engines/workbench/workbench_opaque.c
+++ b/source/blender/draw/engines/workbench/workbench_opaque.c
@@ -126,6 +126,18 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data)
     DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
     DRW_shgroup_uniform_texture(grp, "materialBuffer", wpd->material_buffer_tx);
     DRW_shgroup_uniform_texture(grp, "normalBuffer", wpd->normal_buffer_tx);
+
+    if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
+      BKE_studiolight_ensure_flag(wpd->studio_light,
+                                  STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE |
+                                      STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE);
+      bool use_spec = workbench_is_specular_highlight_enabled(wpd);
+      struct GPUTexture *diff_tx = wpd->studio_light->matcap_diffuse.gputexture;
+      struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture;
+      DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx);
+      DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", use_spec ? spec_tx : diff_tx);
+      DRW_shgroup_uniform_bool_copy(grp, "useSpecular", use_spec);
+    }
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
   }
 }
diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c
index 7a0883e632d..8f3dbb78ac2 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.c
+++ b/source/blender/draw/engines/workbench/workbench_shader.c
@@ -48,6 +48,7 @@ extern char datatoc_workbench_shadow_debug_frag_glsl[];
 extern char datatoc_workbench_cavity_lib_glsl[];
 extern char datatoc_workbench_common_lib_glsl[];
 extern char datatoc_workbench_image_lib_glsl[];
+extern char datatoc_workbench_matcap_lib_glsl[];
 extern char datatoc_workbench_material_lib_glsl[];
 extern char datatoc_workbench_data_lib_glsl[];
 extern char datatoc_workbench_object_outline_lib_glsl[];
@@ -83,6 +84,7 @@ void workbench_shader_library_ensure(void)
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_image_lib);
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_material_lib);
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_data_lib);
+    DRW_SHADER_LIB_ADD(e_data.lib, workbench_matcap_lib);
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_object_outline_lib);
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_curvature_lib);
     DRW_SHADER_LIB_ADD(e_data.lib, workbench_world_light_lib);



More information about the Bf-blender-cvs mailing list