[Bf-blender-cvs] [aae2e1326fe] tmp-workbench-rewrite: Workbench: Refactor: Add cavity support

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


Commit: aae2e1326fe60e8356735dcc079b55727a86bf75
Author: Clément Foucault
Date:   Mon Mar 2 19:11:08 2020 +0100
Branches: tmp-workbench-rewrite
https://developer.blender.org/rBaae2e1326fe60e8356735dcc079b55727a86bf75

Workbench: Refactor: Add cavity support

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
A	source/blender/draw/engines/workbench/shaders/workbench_effect_cavity_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
M	source/blender/draw/engines/workbench/workbench_data.c
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_effect_aa.c
M	source/blender/draw/engines/workbench/workbench_effect_cavity.c
M	source/blender/draw/engines/workbench/workbench_effect_dof.c
M	source/blender/draw/engines/workbench/workbench_effect_taa.c
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/draw/engines/workbench/workbench_render.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 c6935dfdd95..692dc300d89 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -255,6 +255,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_composite_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_deferred_background_frag.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_effect_cavity_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_effect_dof_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_effect_fxaa_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_effect_taa_frag.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
index a0e04f252e2..7031328eb2e 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
@@ -28,7 +28,7 @@ layout(std140) uniform samples_block
 #define ssao_factor_edge ssao_settings.z
 #define ssao_attenuation ssao_settings.w
 
-vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
+vec3 view_space_from_depth(in vec2 uvcoords, in float depth)
 {
   if (WinMatrix[3][3] == 0.0) {
     /* Perspective */
@@ -63,7 +63,7 @@ void main()
 
 #ifdef USE_CAVITY
   float depth = texelFetch(depthBuffer, texel, 0).x;
-  vec3 position = get_view_space_from_depth(screenco, depth);
+  vec3 position = view_space_from_depth(screenco, depth);
   vec3 normal_viewport = workbench_normal_decode(texelFetch(normalBuffer, texel, 0).rg);
 
   ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
index 376b19cdd1b..c1207c0d32f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
@@ -1,77 +1,86 @@
 
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
 
-/*  from The Alchemy screen-space ambient obscurance algorithm
+layout(std140) uniform samples_block
+{
+  vec4 samples_coords[512];
+};
+
+uniform sampler2D cavityJitter;
+
+/*  From The Alchemy screen-space ambient obscurance algorithm
  * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
 
-void ssao_factors(in float depth,
-                  in vec3 normal,
-                  in vec3 position,
-                  in vec2 screenco,
-                  out float cavities,
-                  out float edges)
+void cavity_compute(vec2 screenco,
+                    sampler2D depthBuffer,
+                    sampler2D normalBuffer,
+                    out float cavities,
+                    out float edges)
 {
   cavities = edges = 0.0;
-  /* early out if there is no need for SSAO */
-  if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0) {
+
+  float depth = texture(depthBuffer, screenco).x;
+
+  /* Early out if background */
+  if (depth == 1.0) {
     return;
   }
 
-  /* take the normalized ray direction here */
-  vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb;
+  vec3 position = view_space_from_depth(screenco, depth, world_data.viewvecs, ProjectionMatrix);
+  vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco));
+
+  vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale;
+  vec3 noise = texture(cavityJitter, jitter_co).rgb;
 
   /* find the offset in screen space by multiplying a point
    * in camera space at the depth of the point by the projection matrix. */
   vec2 offset;
-  float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
-  offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
-  offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
+  float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3];
+  offset.x = ProjectionMatrix[0][0] * world_data.cavity_distance / homcoord;
+  offset.y = ProjectionMatrix[1][1] * world_data.cavity_distance / homcoord;
   /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
   offset *= 0.5;
 
-  int num_samples = int(ssao_samples_num);
-
   /* Note. Putting noise usage here to put some ALU after texture fetch. */
   vec2 rotX = noise.rg;
   vec2 rotY = vec2(-rotX.y, rotX.x);
 
-  for (int x = 0; x < num_samples; x++) {
-    int sample_index = x + (int(ssao_iteration) * num_samples);
-    if (sample_index > 500) {
-      continue;
-    }
-    /* ssao_samples[x].xy is sample direction (normalized).
-     * ssao_samples[x].z is sample distance from disk center. */
-
+  int sample_start = world_data.cavity_sample_start;
+  int sample_end = world_data.cavity_sample_end;
+  for (int i = sample_start; i < sample_end && i < 512; i++) {
+    /* sample_coord.xy is sample direction (normalized).
+     * sample_coord.z is sample distance from disk center. */
+    vec3 sample_coord = samples_coords[i].xyz;
     /* Rotate with random direction to get jittered result. */
-    vec2 dir_jittered = vec2(dot(ssao_samples[sample_index].xy, rotX),
-                             dot(ssao_samples[sample_index].xy, rotY));
-    dir_jittered.xy *= ssao_samples[sample_index].z + noise.b;
+    vec2 dir_jittered = vec2(dot(sample_coord.xy, rotX), dot(sample_coord.xy, rotY));
+    dir_jittered.xy *= sample_coord.z + noise.b;
 
-    vec2 uvcoords = screenco.xy + dir_jittered * offset;
-
-    if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0) {
+    vec2 uvcoords = screenco + dir_jittered * offset;
+    /* Out of screen case. */
+    if (any(greaterThan(abs(uvcoords - 0.5), vec2(0.5)))) {
       continue;
     }
-
-    float depth_new = texture(depthBuffer, uvcoords).r;
-
+    /* Sample depth. */
+    float s_depth = texture(depthBuffer, uvcoords).r;
     /* Handle Background case */
-    bool is_background = (depth_new == 1.0);
-
+    bool is_background = (s_depth == 1.0);
     /* This trick provide good edge effect even if no neighbor is found. */
-    vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new);
+    s_depth = (is_background) ? depth : s_depth;
+    vec3 s_pos = view_space_from_depth(uvcoords, s_depth, world_data.viewvecs, ProjectionMatrix);
 
     if (is_background) {
-      pos_new.z -= ssao_distance;
+      s_pos.z -= world_data.cavity_distance;
     }
 
-    vec3 dir = pos_new - position;
+    vec3 dir = s_pos - position;
     float len = length(dir);
     float f_cavities = dot(dir, normal);
     float f_edge = -f_cavities;
     float f_bias = 0.05 * len + 0.0001;
 
-    float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
+    float attenuation = 1.0 / (len * (1.0 + len * len * world_data.cavity_attenuation));
 
     /* use minor bias here to avoid self shadowing */
     if (f_cavities > -f_bias) {
@@ -82,11 +91,10 @@ void ssao_factors(in float depth,
       edges += f_edge * attenuation;
     }
   }
-
-  cavities /= ssao_samples_num;
-  edges /= ssao_samples_num;
+  cavities *= world_data.cavity_sample_count_inv;
+  edges *= world_data.cavity_sample_count_inv;
 
   /* don't let cavity wash out the surface appearance */
-  cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0);
-  edges = edges * ssao_factor_edge;
+  cavities = clamp(cavities * world_data.cavity_valley_factor, 0.0, 1.0);
+  edges = edges * world_data.cavity_ridge_factor;
 }
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 74a745ce74d..0e2eee99a1b 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -77,3 +77,21 @@ vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
     return vec3(0.0, 0.0, 1.0);
   }
 }
+
+vec3 view_space_from_depth(vec2 uvcoords, float depth, vec4 viewvecs[3], mat4 proj_mat)
+{
+  if (proj_mat[3][3] == 0.0) {
+    /* Perspective */
+    float d = 2.0 * depth - 1.0;
+
+    float zview = -proj_mat[3][2] / (d + proj_mat[2][2]);
+
+    return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
+  }
+  else {
+    /* Orthographic */
+    vec3 offset = vec3(uvcoords, depth);
+
+    return viewvecs[0].xyz + offset * viewvecs[1].xyz;
+  }
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
index 22dc906be83..8754b7147d9 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl
@@ -1,6 +1,5 @@
-#ifndef CURVATURE_OFFSET
-#  define CURVATURE_OFFSET 1
-#endif
+
+#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
 
 float curvature_soft_clamp(float curvature, float control)
 {
@@ -10,33 +9,35 @@ float curvature_soft_clamp(float curvature, float control)
   return 0.25 / control;
 }
 
-float calculate_curvature(
-    usampler2D objectId, sampler2D normalBuffer, ivec2 texel, float ridge, float valley)
+void curvature_compute(vec2 uv,
+                       usampler2D objectIdBuffer,
+                       sampler2D normalBuffer,
+                       out float curvature)
 {
-  uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r;
-  uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r;
-  uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r;
-  uint object_right = texelFetchOffset(objectId, texel, 0, ivec2(CURVATURE_OFFSET, 0)).r;
+  curvature = 0.0;
+
+  vec3 offset = ve

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list