[Bf-blender-cvs] [f5549805800] temp-texture-painting-gpu: First working brush stroke.

Jeroen Bakker noreply at git.blender.org
Fri Sep 30 15:50:29 CEST 2022


Commit: f5549805800fad10cb4ecee1d03e543c64f2a937
Author: Jeroen Bakker
Date:   Wed Sep 28 16:52:16 2022 +0200
Branches: temp-texture-painting-gpu
https://developer.blender.org/rBf5549805800fad10cb4ecee1d03e543c64f2a937

First working brush stroke.

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

M	source/blender/blenkernel/BKE_pbvh_pixels.hh
M	source/blender/blenkernel/intern/pbvh_pixels.cc
M	source/blender/editors/sculpt_paint/sculpt_paint_image.cc
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_sculpt_shader_shared.h
M	source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
M	source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_comp.glsl
A	source/blender/gpu/shaders/sculpt_paint/sculpt_paint_image_lib.glsl

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

diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index ca82418fb79..282aebcbcdc 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -36,8 +36,8 @@ struct Triangles {
   void append(const int3 vert_indices)
   {
     TrianglePaintInput triangle;
-    triangle.vert_indices = int4(vert_indices.x, vert_indices.y, vert_indices.z, 0.0f);
-    triangle.delta_barycentric_coord_u = float2(0.0f);
+    triangle.vert_indices = int3(vert_indices.x, vert_indices.y, vert_indices.z);
+    triangle.delta_barycentric_coord = float2(0.0f);
     this->paint_input.append(triangle);
   }
 
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index fdae9d51986..db1a7514b15 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -206,7 +206,7 @@ static void do_encode_pixels(void *__restrict userdata,
       const int maxx = min_ii(ceil(maxu * image_buffer->x), image_buffer->x);
 
       TrianglePaintInput &triangle = triangles.get_paint_input(triangle_index);
-      triangle.delta_barycentric_coord_u = calc_barycentric_delta_x(image_buffer, uvs, minx, miny);
+      triangle.delta_barycentric_coord = calc_barycentric_delta_x(image_buffer, uvs, minx, miny);
       extract_barycentric_pixels(
           tile_data, image_buffer, triangle_index, uvs, minx, miny, maxx, maxy);
     }
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index e6e8a8148e7..9ad15fe4863 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -18,6 +18,7 @@
 #include "GPU_compute.h"
 #include "GPU_debug.h"
 #include "GPU_shader.h"
+#include "GPU_uniform_buffer.h"
 
 #include "IMB_colormanagement.h"
 #include "IMB_imbuf.h"
@@ -258,14 +259,14 @@ template<typename ImageBuffer> class PaintingKernel {
                              const float3 &start_pixel) const
   {
     float3 result = init_pixel_pos(
-        triangle, encoded_pixels.start_barycentric_coord + triangle.delta_barycentric_coord_u);
+        triangle, encoded_pixels.start_barycentric_coord + triangle.delta_barycentric_coord);
     return result - start_pixel;
   }
 
   float3 init_pixel_pos(const TrianglePaintInput &triangle,
                         const float2 &barycentric_weights) const
   {
-    const int4 &vert_indices = triangle.vert_indices;
+    const int3 &vert_indices = triangle.vert_indices;
     float3 result;
     const float3 barycentric(barycentric_weights.x,
                              barycentric_weights.y,
@@ -490,7 +491,9 @@ static void ensure_gpu_buffers(TexturePaintingUserData &data)
 static void gpu_painting_paint_step(TexturePaintingUserData &data,
                                     ImageTileWrapper &image_tile,
                                     ImBuf *image_buffer,
-                                    GPUTexture **tex_ptr)
+                                    GPUTexture **tex_ptr,
+                                    GPUUniformBuf *paint_brush_buf,
+                                    GPUStorageBuf *vert_coord_buf)
 {
   GPUShader *shader = SCULPT_shader_paint_image_get();
   bool texture_needs_clearing = true;
@@ -526,6 +529,9 @@ static void gpu_painting_paint_step(TexturePaintingUserData &data,
 
       GPU_shader_bind(shader);
       GPU_texture_image_bind(tex, GPU_shader_get_texture_binding(shader, "out_img"));
+      GPU_uniformbuf_bind(paint_brush_buf,
+                          GPU_shader_get_uniform_block(shader, "paint_brush_buf"));
+      GPU_storagebuf_bind(vert_coord_buf, GPU_shader_get_ssbo(shader, "vert_coord_buf"));
       GPU_storagebuf_bind(node_data.triangles.gpu_buffer,
                           GPU_shader_get_ssbo(shader, "paint_input"));
       GPU_storagebuf_bind(node_data.gpu_buffers.pixels,
@@ -552,11 +558,73 @@ static void gpu_painting_image_merge(TexturePaintingUserData &UNUSED(data),
   GPU_compute_dispatch(shader, image_buffer.x, image_buffer.y, 1);
 }
 
+static void init_paint_brush_color(const SculptSession &ss,
+                                   const Brush &brush,
+                                   PaintBrushData &r_paint_brush)
+{
+  if (ss.cache->invert) {
+    copy_v3_v3(r_paint_brush.color, BKE_brush_secondary_color_get(ss.scene, &brush));
+  }
+  else {
+    copy_v3_v3(r_paint_brush.color, BKE_brush_color_get(ss.scene, &brush));
+  }
+  /* NOTE: Brush colors are stored in sRGB. We use math color to follow other areas that use
+       brush colors. */
+  srgb_to_linearrgb_v3_v3(r_paint_brush.color, r_paint_brush.color);
+  r_paint_brush.color[3] = 1.0f;
+}
+
+static void init_paint_brush_strength(const SculptSession &ss, PaintBrushData &r_paint_brush)
+{
+  r_paint_brush.strength = ss.cache->bstrength;
+}
+
+/* TODO: Currently only spherical is supported. */
+static void init_paint_brush_test(const SculptSession &ss, PaintBrushData &r_paint_brush)
+{
+  r_paint_brush.test.radius = ss.cache->radius;
+  r_paint_brush.test.location = ss.cache->location;
+  r_paint_brush.test.mirror_symmetry_pass = ss.cache->mirror_symmetry_pass;
+  r_paint_brush.test.symm_rot_mat_inv = ss.cache->symm_rot_mat_inv;
+}
+
+static void init_paint_brush(const SculptSession &ss,
+                             const Brush &brush,
+                             PaintBrushData &r_paint_brush)
+{
+  init_paint_brush_color(ss, brush, r_paint_brush);
+  init_paint_brush_strength(ss, r_paint_brush);
+  init_paint_brush_test(ss, r_paint_brush);
+}
+
+static GPUStorageBuf *gpu_painting_vert_coord_create(SculptSession &ss)
+{
+  Vector<float4> vert_coords;
+
+  vert_coords.reserve(ss.totvert);
+  for (const MVert &mvert : Span<MVert>(ss.mvert, ss.totvert)) {
+    float3 co(mvert.co);
+    vert_coords.append(float4(co.x, co.y, co.z, 0.0f));
+  }
+  GPUStorageBuf *result = GPU_storagebuf_create_ex(
+      sizeof(float4) * ss.totvert, vert_coords.data(), GPU_USAGE_STATIC, __func__);
+  return result;
+}
+
 static void dispatch_gpu_painting(TexturePaintingUserData &data)
 {
+  SculptSession &ss = *data.ob->sculpt;
   ImageUser local_image_user = *data.image_data.image_user;
   GPUTexture *tex = nullptr;
 
+  PaintBrushData paint_brush;
+  init_paint_brush(ss, *data.brush, paint_brush);
+
+  GPUStorageBuf *vert_coord_buf = gpu_painting_vert_coord_create(ss);
+
+  GPUUniformBuf *paint_brush_buf = GPU_uniformbuf_create_ex(
+      sizeof(PaintBrushData), &paint_brush, "PaintBrushData");
+
   LISTBASE_FOREACH (ImageTile *, tile, &data.image_data.image->tiles) {
     ImageTileWrapper image_tile(tile);
     local_image_user.tile = image_tile.get_tile_number();
@@ -567,16 +635,19 @@ static void dispatch_gpu_painting(TexturePaintingUserData &data)
       continue;
     }
 
-    gpu_painting_paint_step(data, image_tile, image_buffer, &tex);
+    gpu_painting_paint_step(data, image_tile, image_buffer, &tex, paint_brush_buf, vert_coord_buf);
     gpu_painting_image_merge(data, *data.image_data.image, local_image_user, *image_buffer, tex);
 
     BKE_image_release_ibuf(data.image_data.image, image_buffer, nullptr);
   }
 
+  /* Clean up temp values. */
+  GPU_uniformbuf_free(paint_brush_buf);
   if (tex) {
     GPU_texture_free(tex);
     tex = nullptr;
   }
+  GPU_storagebuf_free(vert_coord_buf);
 }
 
 /** \} */
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 15e10c6bcf0..8b2945d8385 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -482,6 +482,7 @@ set(GLSL_SRC
   GPU_sculpt_shader_shared.h
   shaders/sculpt_paint/sculpt_paint_image_comp.glsl
   shaders/sculpt_paint/sculpt_paint_image_merge_comp.glsl
+  shaders/sculpt_paint/sculpt_paint_image_lib.glsl
 
   GPU_shader_shared_utils.h
 )
diff --git a/source/blender/gpu/GPU_sculpt_shader_shared.h b/source/blender/gpu/GPU_sculpt_shader_shared.h
index 648cb140188..2688d1790d5 100644
--- a/source/blender/gpu/GPU_sculpt_shader_shared.h
+++ b/source/blender/gpu/GPU_sculpt_shader_shared.h
@@ -10,14 +10,15 @@
 #endif
 
 struct TrianglePaintInput {
-  int4 vert_indices;
+  int3 vert_indices;
+  float _pad0;
   /**
    * Delta barycentric coordinates between 2 neighboring UV's in the U direction.
    *
    * Only the first two coordinates are stored. The third should be recalculated on the fly.
    */
-  float2 delta_barycentric_coord_u;
-  float2 _pad;
+  float2 delta_barycentric_coord;
+  float2 _pad1;
 };
 BLI_STATIC_ASSERT_ALIGN(TrianglePaintInput, 16)
 
@@ -28,15 +29,35 @@ struct PackedPixelRow {
   uint start_image_coordinate;
 
   /**
-   * 16 bits: Number of sequential pixels encoded in this package.
    * 16 bits: Reference to the pbvh triangle index.
+   * 16 bits: Number of sequential pixels encoded in this package.
    */
   uint encoded;
 };
+BLI_STATIC_ASSERT_ALIGN(TrianglePaintInput, 16)
 
 #define PIXEL_ROW_START_IMAGE_COORD(row) \
   ivec2(row.start_image_coordinate & 0xffff, (row.start_image_coordinate & 0xffff0000) >> 16)
 #define PIXEL_ROW_LEN(row) uint(row.encoded & 0xffff);
 #define PIXEL_ROW_PRIM_INDEX(row) uint((row.encoded & 0xffff0000) >> 16)
 
-BLI_STATIC_ASSERT_ALIGN(TrianglePaintInput, 16)
+struct PaintBrushTestData {
+  float4x4 symm_rot_mat_inv;
+  float4 location;
+  float radius;
+  int mirror_symmetry_pass;
+  float _pad0;
+  float _pad1;
+};
+BLI_STATIC_ASSERT_ALIGN(PaintBrushTestData, 16)
+
+struct PaintBrushData {
+  float4 color;
+  PaintBrushTestData test;
+  float strength;
+
+  float _pad0;
+  float _pad1;
+  float _pad2;
+};
+BLI_STATIC_ASSERT_ALIGN(PaintBrushData, 16)
diff --git a/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh b/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
index 3309c8cc739..fe7abdc653f 100644
--- a/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
+++ b/source/blender/gpu/shaders/sculpt_paint/infos/sculpt_paint_image_info.hh
@@ -12,6 +12,8 @@ GPU_SHADER_CREATE_INFO(sculpt_paint_image_compute)
     .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_img")
     .st

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list