diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-07-14 17:18:24 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-07-14 17:47:45 +0300 |
commit | 102f66c0a4b1f1013aa6bb061c9a2627f4252031 (patch) | |
tree | 4cf86c4a777034b7c2715605565f4fe2fccc942c /source/blender/draw/intern | |
parent | 5e1212368510e97e519d151ce19d77ed56f1a565 (diff) |
PointCloud: Initial rendering support for Workbench
Also includes outline overlays. Removes the temp overlay drawing
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_pointcloud.c | 46 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_pointcloud_lib.glsl | 138 |
5 files changed, 61 insertions, 132 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 0a2cd106fd2..20e346375a7 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -829,7 +829,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob) case OB_HAIR: return NULL; case OB_POINTCLOUD: - return NULL; + return DRW_pointcloud_batch_cache_get_dots(ob); case OB_VOLUME: return DRW_cache_volume_face_wireframe_get(ob); case OB_GPENCIL: { @@ -958,7 +958,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob, case OB_HAIR: return NULL; case OB_POINTCLOUD: - return NULL; + return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len); case OB_VOLUME: return NULL; default: diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 6279d6d8ea0..96d351794e6 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -145,6 +145,9 @@ int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud); struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob); struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob); +struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob, + struct GPUMaterial **gpumat_array, + uint gpumat_array_len); /* Volume */ int DRW_volume_material_count_get(struct Volume *volume); diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c index 897703c71ec..78d67a772bf 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c @@ -52,9 +52,12 @@ typedef struct PointCloudBatchCache { GPUBatch *dots; GPUBatch *surface; + GPUBatch **surface_per_mat; /* settings to determine if cache is invalid */ bool is_dirty; + + int mat_len; } PointCloudBatchCache; /* GPUBatch cache management. */ @@ -62,7 +65,14 @@ typedef struct PointCloudBatchCache { static bool pointcloud_batch_cache_valid(PointCloud *pointcloud) { PointCloudBatchCache *cache = pointcloud->batch_cache; - return (cache && cache->is_dirty == false); + + if (cache == NULL) { + return false; + } + if (cache->mat_len != DRW_pointcloud_material_count_get(pointcloud)) { + return false; + } + return cache->is_dirty == false; } static void pointcloud_batch_cache_init(PointCloud *pointcloud) @@ -76,6 +86,10 @@ static void pointcloud_batch_cache_init(PointCloud *pointcloud) memset(cache, 0, sizeof(*cache)); } + cache->mat_len = DRW_pointcloud_material_count_get(pointcloud); + cache->surface_per_mat = MEM_callocN(sizeof(GPUBatch *) * cache->mat_len, + "pointcloud suface_per_mat"); + cache->is_dirty = false; } @@ -119,6 +133,13 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud) GPU_VERTBUF_DISCARD_SAFE(cache->pos); GPU_VERTBUF_DISCARD_SAFE(cache->geom); GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices); + + if (cache->surface_per_mat) { + for (int i = 0; i < cache->mat_len; i++) { + GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]); + } + } + MEM_SAFE_FREE(cache->surface_per_mat); } void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud) @@ -138,7 +159,7 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache * static GPUVertFormat format = {0}; if (format.attr_len == 0) { /* initialize vertex format */ - GPU_vertformat_attr_add(&format, "ptcloud", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } cache->pos = GPU_vertbuf_create_with_format(&format); @@ -198,7 +219,7 @@ static void pointcloud_batch_cache_ensure_geom(Object *UNUSED(ob), PointCloudBat static uint pos; if (format.attr_len == 0) { /* initialize vertex format */ - pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(&format, "pos_inst", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); GPU_vertformat_alias_add(&format, "nor"); } @@ -249,6 +270,25 @@ GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob) return cache->surface; } +GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob, + struct GPUMaterial **UNUSED(gpumat_array), + uint gpumat_array_len) +{ + PointCloud *pointcloud = ob->data; + PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud); + BLI_assert(cache->mat_len == gpumat_array_len); + + if (cache->surface_per_mat[0] == NULL) { + pointcloud_batch_cache_ensure_pos(ob, cache); + pointcloud_batch_cache_ensure_geom(ob, cache); + + cache->surface_per_mat[0] = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices); + GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false); + } + + return cache->surface_per_mat; +} + int DRW_pointcloud_material_count_get(PointCloud *pointcloud) { return max_ii(1, pointcloud->totcol); diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 3d83b918757..14d77ab1b21 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -793,10 +793,10 @@ void DRW_shgroup_call_range( drw_command_draw_range(shgroup, geom, handle, v_sta, v_ct); } +/* A count of 0 instance will use the default number of instance in the batch. */ void DRW_shgroup_call_instance_range( DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct) { - BLI_assert(i_ct > 0); BLI_assert(geom != NULL); if (G.f & G_FLAG_PICKSEL) { drw_command_set_select_id(shgroup, NULL, DST.select_id); diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl index 9636495a539..7545d7c89f3 100644 --- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl +++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl @@ -1,136 +1,22 @@ -/** - * Library to create hairs dynamically from control points. - * This is less bandwidth intensive than fetching the vertex attributes - * but does more ALU work per vertex. This also reduces the amount - * of data the CPU has to precompute and transfer for each update. - */ -/** - * hairStrandsRes: Number of points per hair strand. - * 2 - no subdivision - * 3+ - 1 or more interpolated points per hair. - */ -uniform int hairStrandsRes = 8; +/* NOTE: To be used with UNIFORM_RESOURCE_ID and INSTANCED_ATTR as define. */ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) -/** - * hairThicknessRes : Subdiv around the hair. - * 1 - Wire Hair: Only one pixel thick, independent of view distance. - * 2 - Polystrip Hair: Correct width, flat if camera is parallel. - * 3+ - Cylinder Hair: Massive calculation but potentially perfect. Still need proper support. - */ -uniform int hairThicknessRes = 1; +in vec4 pos; /* Position and radius. */ -/* Hair thickness shape. */ -uniform float hairRadRoot = 0.01; -uniform float hairRadTip = 0.0; -uniform float hairRadShape = 0.5; -uniform bool hairCloseTip = true; +/* ---- Instanced attribs ---- */ -uniform vec4 hairDupliMatrix[4]; +in vec3 pos_inst; +in vec3 nor; -/* -- Per control points -- */ -uniform samplerBuffer hairPointBuffer; /* RGBA32F */ -#define point_position xyz -#define point_time w /* Position along the hair length */ - -/* -- Per strands data -- */ -uniform usamplerBuffer hairStrandBuffer; /* R32UI */ -uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */ - -/* Not used, use one buffer per uv layer */ -// uniform samplerBuffer hairUVBuffer; /* RG32F */ -// uniform samplerBuffer hairColBuffer; /* RGBA16 linear color */ - -/* -- Subdivision stage -- */ -/** - * We use a transform feedback 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. - */ - -#ifdef HAIR_PHASE_SUBDIV -int hair_get_base_id(float local_time, int strand_segments, out float interp_time) +/* Return object position. */ +vec3 pointcloud_get_pos(void) { - float time_per_strand_seg = 1.0 / float(strand_segments); - - float ratio = local_time / time_per_strand_seg; - interp_time = fract(ratio); - - return int(ratio); + return pos.xyz + pos_inst * pos.w; } -void hair_get_interp_attrs( - out vec4 data0, out vec4 data1, out vec4 data2, out vec4 data3, out float interp_time) -{ - float local_time = float(gl_VertexID % hairStrandsRes) / float(hairStrandsRes - 1); - - int hair_id = gl_VertexID / hairStrandsRes; - int strand_offset = int(texelFetch(hairStrandBuffer, hair_id).x); - int strand_segments = int(texelFetch(hairStrandSegBuffer, hair_id).x); - - int id = hair_get_base_id(local_time, strand_segments, interp_time); - - int ofs_id = id + strand_offset; - - data0 = texelFetch(hairPointBuffer, ofs_id - 1); - data1 = texelFetch(hairPointBuffer, ofs_id); - data2 = texelFetch(hairPointBuffer, ofs_id + 1); - data3 = texelFetch(hairPointBuffer, ofs_id + 2); - - if (id <= 0) { - /* root points. Need to reconstruct previous data. */ - data0 = data1 * 2.0 - data2; - } - if (id + 1 >= strand_segments) { - /* tip points. Need to reconstruct next data. */ - data3 = data2 * 2.0 - data1; - } -} -#endif - -/* -- Drawing stage -- */ -/** - * For final drawing, the vertex index and the number of vertex per segment - */ - -#ifndef HAIR_PHASE_SUBDIV -int hair_get_strand_id(void) +/* Return object Normal. */ +vec3 pointcloud_get_nor(void) { - return gl_VertexID / (hairStrandsRes * hairThicknessRes); + return nor; } - -int hair_get_base_id(void) -{ - return gl_VertexID / hairThicknessRes; -} - -/* Copied from cycles. */ -float hair_shaperadius(float shape, float root, float tip, float time) -{ - float radius = 1.0 - time; - - if (shape < 0.0) { - radius = pow(radius, 1.0 + shape); - } - else { - radius = pow(radius, 1.0 / (1.0 - shape)); - } - - if (hairCloseTip && (time > 0.99)) { - return 0.0; - } - - return (radius * (root - tip)) + tip; -} - -# ifdef OS_MAC -in float dummy; -# endif - -vec3 pointcloud_get_pos() -{ -} - -#endif |