diff options
Diffstat (limited to 'source/blender')
8 files changed, 129 insertions, 24 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 6c55fa7ce30..a74a255045a 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -307,6 +307,10 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC) data_to_c_simple(engines/select/shaders/selection_id_3D_vert.glsl SRC) data_to_c_simple(engines/select/shaders/selection_id_frag.glsl SRC) +data_to_c_simple(engines/basic/shaders/conservative_depth_geom.glsl SRC) +data_to_c_simple(engines/basic/shaders/conservative_depth_vert.glsl SRC) +data_to_c_simple(engines/basic/shaders/conservative_depth_frag.glsl SRC) + data_to_c_simple(engines/overlay/shaders/antialiasing_frag.glsl SRC) data_to_c_simple(engines/overlay/shaders/antialiasing_vert.glsl SRC) data_to_c_simple(engines/overlay/shaders/armature_dof_vert.glsl SRC) 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 +} diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl index a2fa82d151e..4d705a4ee2b 100644 --- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl @@ -148,6 +148,12 @@ void main() edgeStart = vec2(-1.0); } +#ifdef SELECT_EDGES + /* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the + * wire to at least create one fragment that will pass the occlusion query. */ + gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0); +#endif + #ifdef USE_WORLD_CLIP_PLANES world_clip_planes_calc_clip_distance(wpos); #endif diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 7397490d406..3dc775f92c4 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1378,7 +1378,7 @@ static void drw_engines_enable_overlays(void) */ static void drw_engines_enable_basic(void) { - use_drw_engine(DRW_engine_viewport_basic_type.draw_engine); + use_drw_engine(&draw_engine_basic_type); } static void drw_engines_enable(ViewLayer *UNUSED(view_layer), @@ -2830,6 +2830,7 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_overlay_type); DRW_engine_register(&draw_engine_select_type); + DRW_engine_register(&draw_engine_basic_type); /* setup callbacks */ { |