Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-02-04 17:19:28 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-02-04 17:20:15 +0300
commit3685347b417259f08060d914b4447d0190a5f57e (patch)
tree32510de275d9553b4f537a1f87b5edf640126061 /source/blender/draw/engines/basic
parentcd0a02862404676622c96812fcd5b6ef20a2ec78 (diff)
Selection: Add conservative rasterization to select really small objects
The conservative depth shader is ~4.5x slower than the normal one as it uses geometry shader and fragment shader discard. This patch also includes a hack to also fix the view parallel planar geometry and the really small wire objects. For some reason, the conservative raster fix does not work with normal selection but does with box select. This is a fix for T63356. Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D6714
Diffstat (limited to 'source/blender/draw/engines/basic')
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c58
-rw-r--r--source/blender/draw/engines/basic/basic_engine.h1
-rw-r--r--source/blender/draw/engines/basic/shaders/conservative_depth_frag.glsl5
-rw-r--r--source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl59
-rw-r--r--source/blender/draw/engines/basic/shaders/conservative_depth_vert.glsl17
5 files changed, 117 insertions, 23 deletions
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index fcbe227ca1b..79da067095a 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -37,6 +37,12 @@
#define BASIC_ENGINE "BLENDER_BASIC"
+extern char datatoc_conservative_depth_frag_glsl[];
+extern char datatoc_conservative_depth_vert_glsl[];
+extern char datatoc_conservative_depth_geom_glsl[];
+
+extern char datatoc_common_view_lib_glsl[];
+
/* *********** LISTS *********** */
/* GPUViewport.storage
@@ -61,6 +67,7 @@ typedef struct BASIC_Data {
typedef struct BASIC_Shaders {
/* Depth Pre Pass */
struct GPUShader *depth;
+ struct GPUShader *depth_conservative;
} BASIC_Shaders;
/* *********** STATIC *********** */
@@ -84,6 +91,22 @@ static void basic_engine_init(void *UNUSED(vedata))
/* Depth prepass */
if (!sh_data->depth) {
sh_data->depth = DRW_shader_create_3d_depth_only(draw_ctx->sh_cfg);
+
+ const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
+ sh_data->depth_conservative = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_conservative_depth_vert_glsl,
+ NULL},
+ .geom = (const char *[]){sh_cfg->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_conservative_depth_geom_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_conservative_depth_frag_glsl,
+ NULL},
+ .defs = (const char *[]){sh_cfg->def, NULL},
+ });
}
}
@@ -91,6 +114,7 @@ static void basic_cache_init(void *vedata)
{
BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+ DRWShadingGroup *grp;
const DRWContextState *draw_ctx = DRW_context_state_get();
BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
@@ -106,12 +130,18 @@ static void basic_cache_init(void *vedata)
DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
+ GPUShader *sh = DRW_state_is_select() ? sh_data->depth_conservative : sh_data->depth;
+
DRW_PASS_CREATE(psl->depth_pass[i], state | clip_state | infront_state);
- stl->g_data->depth_shgrp[i] = DRW_shgroup_create(sh_data->depth, psl->depth_pass[i]);
+ stl->g_data->depth_shgrp[i] = grp = DRW_shgroup_create(sh, psl->depth_pass[i]);
+ DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
state |= DRW_STATE_CULL_BACK;
DRW_PASS_CREATE(psl->depth_pass_cull[i], state | clip_state | infront_state);
- stl->g_data->depth_shgrp_cull[i] = DRW_shgroup_create(sh_data->depth, psl->depth_pass_cull[i]);
+ stl->g_data->depth_shgrp_cull[i] = grp = DRW_shgroup_create(sh, psl->depth_pass_cull[i]);
+ DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
}
}
@@ -197,7 +227,10 @@ static void basic_draw_scene(void *vedata)
static void basic_engine_free(void)
{
- /* all shaders are builtin */
+ for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) {
+ BASIC_Shaders *sh_data = &e_data.sh_data[i];
+ DRW_SHADER_FREE_SAFE(sh_data->depth_conservative);
+ }
}
static const DrawEngineDataSize basic_data_size = DRW_VIEWPORT_DATA_SIZE(BASIC_Data);
@@ -219,23 +252,4 @@ DrawEngineType draw_engine_basic_type = {
NULL,
};
-/* Note: currently unused, we may want to register so we can see this when debugging the view. */
-
-RenderEngineType DRW_engine_viewport_basic_type = {
- NULL,
- NULL,
- BASIC_ENGINE,
- N_("Basic"),
- RE_INTERNAL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &draw_engine_basic_type,
- {NULL, NULL, NULL},
-};
-
#undef BASIC_ENGINE
diff --git a/source/blender/draw/engines/basic/basic_engine.h b/source/blender/draw/engines/basic/basic_engine.h
index a32467786de..d17f1c24c37 100644
--- a/source/blender/draw/engines/basic/basic_engine.h
+++ b/source/blender/draw/engines/basic/basic_engine.h
@@ -24,6 +24,5 @@
#define __BASIC_ENGINE_H__
extern DrawEngineType draw_engine_basic_type;
-extern RenderEngineType DRW_engine_viewport_basic_type;
#endif /* __BASIC_ENGINE_H__ */
diff --git a/source/blender/draw/engines/basic/shaders/conservative_depth_frag.glsl b/source/blender/draw/engines/basic/shaders/conservative_depth_frag.glsl
new file mode 100644
index 00000000000..cedb0059794
--- /dev/null
+++ b/source/blender/draw/engines/basic/shaders/conservative_depth_frag.glsl
@@ -0,0 +1,5 @@
+
+void main()
+{
+ /* Passthrough shader. */
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl b/source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl
new file mode 100644
index 00000000000..fc5ea221348
--- /dev/null
+++ b/source/blender/draw/engines/basic/shaders/conservative_depth_geom.glsl
@@ -0,0 +1,59 @@
+
+/* Adaptation of Conservative Rasterization
+ * from GPU Gems 2
+ * Using method 2.
+ *
+ * Actual final implementation does not do conservative rasterization and only
+ * avoids triangles producing no fragments.
+ */
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+RESOURCE_ID_VARYING
+
+uniform vec2 sizeViewport;
+uniform vec2 sizeViewportInv;
+
+void main()
+{
+ /* Compute plane normal in ndc space. */
+ vec3 pos0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
+ vec3 pos1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
+ vec3 pos2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w;
+ vec3 plane = normalize(cross(pos1 - pos0, pos2 - pos0));
+ /* Compute NDC bound box. */
+ vec4 bbox = vec4(min(min(pos0.xy, pos1.xy), pos2.xy), max(max(pos0.xy, pos1.xy), pos2.xy));
+ /* Convert to pixel space. */
+ bbox = (bbox * 0.5 + 0.5) * sizeViewport.xyxy;
+ /* Detect failure cases where triangles would produce no fragments. */
+ bvec2 is_subpixel = lessThan(bbox.zw - bbox.xy, vec2(1.0));
+ /* View aligned triangle. */
+ const float threshold = 0.00001;
+ bool is_coplanar = abs(plane.z) < threshold;
+
+ for (int i = 0; i < 3; i++) {
+ gl_Position = gl_in[i].gl_Position;
+ if (all(is_subpixel)) {
+ vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(2.0, -1.0) : vec2(-1.0, 2.0));
+ /* HACK: Fix cases where the triangle is too small make it cover at least one pixel. */
+ gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ofs;
+ }
+ /* Test if the triangle is almost parralele with the view to avoid precision issues. */
+ else if (any(is_subpixel) || is_coplanar) {
+ /* HACK: Fix cases where the triangle is Parallel to the view by deforming it slightly. */
+ vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(1.0, -1.0) : vec2(1.0));
+ gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ofs;
+ }
+ else {
+ /* Triangle expansion should happen here, but we decide to not implement it for
+ * depth precision & performance reasons. */
+ }
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_set_clip_distance(gl_in[i].gl_ClipDistance);
+#endif
+ EmitVertex();
+ }
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/basic/shaders/conservative_depth_vert.glsl b/source/blender/draw/engines/basic/shaders/conservative_depth_vert.glsl
new file mode 100644
index 00000000000..c55a3211ff2
--- /dev/null
+++ b/source/blender/draw/engines/basic/shaders/conservative_depth_vert.glsl
@@ -0,0 +1,17 @@
+
+RESOURCE_ID_VARYING
+
+in vec3 pos;
+
+void main()
+{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+ PASS_RESOURCE_ID
+
+ vec3 world_pos = point_object_to_world(pos);
+ gl_Position = point_world_to_ndc(world_pos);
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(world_pos);
+#endif
+}