[Bf-blender-cvs] [998d7a9f851] temp-gpu-compute-shader-hair: Separate vertex and compute shaders.

Jeroen Bakker noreply at git.blender.org
Fri May 7 15:54:52 CEST 2021


Commit: 998d7a9f851b7e4686b999dbfe00da5eaa91e262
Author: Jeroen Bakker
Date:   Fri May 7 15:48:01 2021 +0200
Branches: temp-gpu-compute-shader-hair
https://developer.blender.org/rB998d7a9f851b7e4686b999dbfe00da5eaa91e262

Separate vertex and compute shaders.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/intern/draw_hair.c
M	source/blender/draw/intern/shaders/common_hair_lib.glsl
A	source/blender/draw/intern/shaders/common_hair_refine_comp.glsl
M	source/blender/draw/intern/shaders/common_hair_refine_vert.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 196b46953c4..0d9c470c8c5 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -321,6 +321,7 @@ data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
 data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC)
 data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
 data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
+data_to_c_simple(intern/shaders/common_hair_refine_comp.glsl SRC)
 data_to_c_simple(intern/shaders/common_math_lib.glsl SRC)
 data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC)
 data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 1198d71a296..c839dbed715 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -46,11 +46,12 @@
 
 #ifndef __APPLE__
 #  define USE_TRANSFORM_FEEDBACK
+#  define USE_COMPUTE_SHADERS
 #endif
 
 BLI_INLINE bool drw_hair_use_compute_shaders(void)
 {
-#ifdef USE_TRANSFORM_FEEDBACK
+#ifdef USE_COMPUTE_SHADERS
   return GPU_compute_shader_support();
 #else
   return false;
@@ -83,6 +84,7 @@ static DRWPass *g_tf_pass; /* XXX can be a problem with multiple DRWManager in t
 
 extern char datatoc_common_hair_lib_glsl[];
 extern char datatoc_common_hair_refine_vert_glsl[];
+extern char datatoc_common_hair_refine_comp_glsl[];
 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
 
 static GPUShader *hair_refine_shader_get(ParticleRefineShader sh)
@@ -91,16 +93,18 @@ static GPUShader *hair_refine_shader_get(ParticleRefineShader sh)
     return g_refine_shaders[sh];
   }
 
-#ifdef USE_TRANSFORM_FEEDBACK
+#ifdef USE_COMPUTE_SHADERS
   const bool do_compute = drw_hair_use_compute_shaders();
   if (do_compute) {
-    g_refine_shaders[sh] = GPU_shader_create_compute(datatoc_common_hair_refine_vert_glsl,
+    g_refine_shaders[sh] = GPU_shader_create_compute(datatoc_common_hair_refine_comp_glsl,
                                                      datatoc_common_hair_lib_glsl,
                                                      "#define HAIR_PHASE_SUBDIV\n",
                                                      __func__);
     return g_refine_shaders[sh];
   }
+#endif
 
+#ifdef USE_TRANSFORM_FEEDBACK
   char *shader_src = BLI_string_joinN(datatoc_common_hair_lib_glsl,
                                       datatoc_common_hair_refine_vert_glsl);
   const char *var_names[1] = {"finalColor"};
@@ -123,7 +127,7 @@ static GPUShader *hair_refine_shader_get(ParticleRefineShader sh)
 
 void DRW_hair_init(void)
 {
-#ifdef USE_TRANSFORM_FEEDBACK
+#if defined(USE_TRANSFORM_FEEDBACK) || defined(USE_COMPUTE_SHADERS)
   g_tf_pass = DRW_pass_create("Update Hair Pass", 0);
 #else
   g_tf_pass = DRW_pass_create("Update Hair Pass", DRW_STATE_WRITE_COLOR);
diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl
index 1f82fd341c9..a765e5e87cc 100644
--- a/source/blender/draw/intern/shaders/common_hair_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl
@@ -43,8 +43,8 @@ uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */
 
 /* -- Subdivision stage -- */
 /**
- * We use a transform feedback or compute shader to preprocess the strands and add more subdivision to it.
- * For the moment these are simple smooth interpolation but one could hope to see the full
+ * We use a transform feedback or compute shader to preprocess the strands and add more subdivision
+ * to it. For the moment these are simple smooth interpolation but one could hope to see the full
  * children particle modifiers being evaluated at this stage.
  *
  * If no more subdivision is needed, we can skip this step.
@@ -252,3 +252,45 @@ vec2 hair_resolve_barycentric(vec2 vert_barycentric)
     return vec2(1.0 - vert_barycentric.x, 0.0);
   }
 }
+
+/* Hair interpolation functions. */
+vec4 hair_get_weights_cardinal(float t)
+{
+  float t2 = t * t;
+  float t3 = t2 * t;
+#if defined(CARDINAL)
+  float fc = 0.71;
+#else /* defined(CATMULL_ROM) */
+  float fc = 0.5;
+#endif
+
+  vec4 weights;
+  /* GLSL Optimized version of key_curve_position_weights() */
+  float fct = t * fc;
+  float fct2 = t2 * fc;
+  float fct3 = t3 * fc;
+  weights.x = (fct2 * 2.0 - fct3) - fct;
+  weights.y = (t3 * 2.0 - fct3) + (-t2 * 3.0 + fct2) + 1.0;
+  weights.z = (-t3 * 2.0 + fct3) + (t2 * 3.0 - (2.0 * fct2)) + fct;
+  weights.w = fct3 - fct2;
+  return weights;
+}
+
+/* TODO(fclem): This one is buggy, find why. (it's not the optimization!!) */
+vec4 hair_get_weights_bspline(float t)
+{
+  float t2 = t * t;
+  float t3 = t2 * t;
+
+  vec4 weights;
+  /* GLSL Optimized version of key_curve_position_weights() */
+  weights.xz = vec2(-0.16666666, -0.5) * t3 + (0.5 * t2 + 0.5 * vec2(-t, t) + 0.16666666);
+  weights.y = (0.5 * t3 - t2 + 0.66666666);
+  weights.w = (0.16666666 * t3);
+  return weights;
+}
+
+vec4 hair_interp_data(vec4 v0, vec4 v1, vec4 v2, vec4 v3, vec4 w)
+{
+  return v0 * w.x + v1 * w.y + v2 * w.z + v3 * w.w;
+}
diff --git a/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl b/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl
new file mode 100644
index 00000000000..4dca2bb09dc
--- /dev/null
+++ b/source/blender/draw/intern/shaders/common_hair_refine_comp.glsl
@@ -0,0 +1,23 @@
+
+/*
+ * To be compiled with common_hair_lib.glsl.
+ */
+
+layout(local_size_x = 1, local_size_y = 1) in;
+layout(std430, binding = 0) buffer hairPointOutputBuffer
+{
+  vec4 Positions[];
+};
+
+void main(void)
+{
+  float interp_time;
+  vec4 data0, data1, data2, data3;
+  hair_get_interp_attrs(data0, data1, data2, data3, interp_time);
+
+  vec4 weights = hair_get_weights_cardinal(interp_time);
+  vec4 result = hair_interp_data(data0, data1, data2, data3, weights);
+
+  int index = int(gl_GlobalInvocationID.x) * hairStrandsRes + int(gl_GlobalInvocationID.y);
+  Positions[index] = result;
+}
diff --git a/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl b/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
index 317a4abffa6..7b33bfa6859 100644
--- a/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
+++ b/source/blender/draw/intern/shaders/common_hair_refine_vert.glsl
@@ -1,61 +1,9 @@
 
 /*
  * To be compiled with common_hair_lib.glsl.
- * Shader can be used as a vertex or a compute shader.
  */
 
-#ifdef GPU_VERTEX_SHADER
 out vec4 finalColor;
-#endif
-
-#ifdef GPU_COMPUTE_SHADER
-layout(local_size_x = 1, local_size_y = 1) in;
-layout(std430, binding = 0) buffer hairPointOutputBuffer
-{
-  vec4 Positions[];
-};
-#endif
-
-vec4 get_weights_cardinal(float t)
-{
-  float t2 = t * t;
-  float t3 = t2 * t;
-#if defined(CARDINAL)
-  float fc = 0.71;
-#else /* defined(CATMULL_ROM) */
-  float fc = 0.5;
-#endif
-
-  vec4 weights;
-  /* GLSL Optimized version of key_curve_position_weights() */
-  float fct = t * fc;
-  float fct2 = t2 * fc;
-  float fct3 = t3 * fc;
-  weights.x = (fct2 * 2.0 - fct3) - fct;
-  weights.y = (t3 * 2.0 - fct3) + (-t2 * 3.0 + fct2) + 1.0;
-  weights.z = (-t3 * 2.0 + fct3) + (t2 * 3.0 - (2.0 * fct2)) + fct;
-  weights.w = fct3 - fct2;
-  return weights;
-}
-
-/* TODO(fclem): This one is buggy, find why. (it's not the optimization!!) */
-vec4 get_weights_bspline(float t)
-{
-  float t2 = t * t;
-  float t3 = t2 * t;
-
-  vec4 weights;
-  /* GLSL Optimized version of key_curve_position_weights() */
-  weights.xz = vec2(-0.16666666, -0.5) * t3 + (0.5 * t2 + 0.5 * vec2(-t, t) + 0.16666666);
-  weights.y = (0.5 * t3 - t2 + 0.66666666);
-  weights.w = (0.16666666 * t3);
-  return weights;
-}
-
-vec4 interp_data(vec4 v0, vec4 v1, vec4 v2, vec4 v3, vec4 w)
-{
-  return v0 * w.x + v1 * w.y + v2 * w.z + v3 * w.w;
-}
 
 #ifdef TF_WORKAROUND
 uniform int targetWidth;
@@ -69,13 +17,12 @@ void main(void)
   vec4 data0, data1, data2, data3;
   hair_get_interp_attrs(data0, data1, data2, data3, interp_time);
 
-  vec4 weights = get_weights_cardinal(interp_time);
-  vec4 result = interp_data(data0, data1, data2, data3, weights);
+  vec4 weights = hair_get_weights_cardinal(interp_time);
+  vec4 result = hair_interp_data(data0, data1, data2, data3, weights);
 
-#ifdef GPU_VERTEX_SHADER
   finalColor = result;
 
-#  ifdef TF_WORKAROUND
+#ifdef TF_WORKAROUND
   int id = gl_VertexID - idOffset;
   gl_Position.x = ((float(id % targetWidth) + 0.5) / float(targetWidth)) * 2.0 - 1.0;
   gl_Position.y = ((float(id / targetWidth) + 0.5) / float(targetHeight)) * 2.0 - 1.0;
@@ -83,11 +30,5 @@ void main(void)
   gl_Position.w = 1.0;
 
   gl_PointSize = 1.0;
-#  endif
-#endif
-
-#ifdef GPU_COMPUTE_SHADER
-  int index = int(gl_GlobalInvocationID.x) * hairStrandsRes + int(gl_GlobalInvocationID.y);
-  Positions[index] = result;
 #endif
 }



More information about the Bf-blender-cvs mailing list