[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