Overlay-Next: Prepass: Grease Pencil

Allow selection of grease pencil objects.

Rel #102179

Pull Request: https://projects.blender.org/blender/blender/pulls/127238
This commit is contained in:
Clément FOUCAULT
2024-09-06 13:29:53 +02:00
committed by Clément Foucault
parent a0f653c002
commit a4cd59e369
9 changed files with 156 additions and 9 deletions

View File

@@ -661,6 +661,8 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_clipbound_vert.glsl
engines/overlay/shaders/overlay_common_lib.glsl
engines/overlay/shaders/overlay_depth_only_frag.glsl
engines/overlay/shaders/overlay_depth_only_gpencil_frag.glsl
engines/overlay/shaders/overlay_depth_only_gpencil_vert.glsl
engines/overlay/shaders/overlay_depth_only_vert.glsl
engines/overlay/shaders/overlay_edit_curve_handle_geom.glsl
engines/overlay/shaders/overlay_edit_curve_handle_next_vert.glsl

View File

@@ -96,6 +96,7 @@ GPU_SHADER_CREATE_INFO(eevee_geom_gpencil)
.vertex_source("eevee_geom_gpencil_vert.glsl")
.vertex_out(eevee_surf_iface)
.additional_info("draw_gpencil_new",
"draw_modelmat_new",
"draw_object_infos_new",
"draw_resource_id_varying",
"draw_resource_id_new");

View File

@@ -49,7 +49,8 @@ class GreasePencil {
const ViewParameters &view,
const Scene *scene,
Object *ob,
ResourceHandle res_handle)
ResourceHandle res_handle,
select::ID select_id = select::SelectMap::select_invalid_id())
{
using namespace blender;
using namespace blender::ed::greasepencil;
@@ -117,7 +118,7 @@ class GreasePencil {
if (show_fill) {
int v_first = t_offset * 3;
int v_count = num_stroke_triangles * 3;
pass.draw(geom, 1, v_count, v_first, res_handle);
pass.draw(geom, 1, v_count, v_first, res_handle, select_id.get());
}
t_offset += num_stroke_triangles;
@@ -125,7 +126,7 @@ class GreasePencil {
if (show_stroke) {
int v_first = t_offset * 3;
int v_count = num_stroke_vertices * 2 * 3;
pass.draw(geom, 1, v_count, v_first, res_handle);
pass.draw(geom, 1, v_count, v_first, res_handle, select_id.get());
}
t_offset += num_stroke_vertices * 2;
});

View File

@@ -15,6 +15,7 @@
#include "draw_sculpt.hh"
#include "overlay_next_grease_pencil.hh"
#include "overlay_next_private.hh"
namespace blender::draw::overlay {
@@ -28,12 +29,12 @@ class Prepass {
PassMain::Sub *hair_ps_ = nullptr;
PassMain::Sub *curves_ps_ = nullptr;
PassMain::Sub *point_cloud_ps_ = nullptr;
PassMain::Sub *grease_pencil_ps_ = nullptr;
bool enabled_ = false;
bool use_material_slot_selection_ = false;
/* For working with material. Should be removed at some point with better interface. */
Vector<gpu::Batch *> geom_array_;
overlay::GreasePencil::ViewParameters grease_pencil_view;
public:
Prepass(const SelectionType selection_type) : selection_type_(selection_type){};
@@ -52,6 +53,14 @@ class Prepass {
return;
}
{
/* TODO(fclem): This is against design. We should not sync depending on view position.
* Eventually, we should do this in a compute shader prepass. */
float4x4 viewinv;
DRW_view_viewmat_get(nullptr, viewinv.ptr(), true);
grease_pencil_view = {DRW_view_is_persp_get(nullptr), viewinv};
}
use_material_slot_selection_ = DRW_state_is_material_select();
const View3DShading &shading = state.v3d->shading;
@@ -86,6 +95,12 @@ class Prepass {
sub.bind_ubo("globalsBlock", &res.globals_buf);
point_cloud_ps_ = &sub;
}
{
auto &sub = ps_.sub("GreasePencil");
sub.shader_set(res.shaders.depth_grease_pencil.get());
sub.bind_ubo("globalsBlock", &res.globals_buf);
grease_pencil_ps_ = &sub;
}
}
void particle_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res, const State &state)
@@ -201,6 +216,19 @@ class Prepass {
geom_single = curves_sub_pass_setup(*curves_ps_, state.scene, ob_ref.object);
pass = curves_ps_;
break;
case OB_GREASE_PENCIL:
if (selection_type_ == SelectionType::DISABLED) {
/* Disable during display, only enable for selection.
* The grease pencil engine already renders it properly. */
return;
}
GreasePencil::draw_grease_pencil(*grease_pencil_ps_,
grease_pencil_view,
state.scene,
ob_ref.object,
manager.resource_handle(ob_ref),
res.select_id(ob_ref));
return;
default:
break;
}

View File

@@ -231,6 +231,7 @@ class ShaderModule {
ShaderPtr armature_stick;
ShaderPtr armature_wire;
ShaderPtr depth_curves = selectable_shader("overlay_depth_curves");
ShaderPtr depth_grease_pencil = selectable_shader("overlay_depth_gpencil");
ShaderPtr depth_mesh = selectable_shader("overlay_depth_mesh");
ShaderPtr depth_point_cloud = selectable_shader("overlay_depth_pointcloud");
ShaderPtr extra_grid;

View File

@@ -792,6 +792,31 @@ GPU_SHADER_CREATE_INFO(overlay_depth_mesh)
.fragment_source("overlay_depth_only_frag.glsl")
.additional_info("draw_globals", "draw_view", "draw_modelmat_new", "draw_resource_handle_new");
GPU_SHADER_INTERFACE_INFO(overlay_depth_only_gpencil_flat_iface, "gp_interp_flat")
.flat(Type::VEC2, "aspect")
.flat(Type::VEC4, "sspos");
GPU_SHADER_INTERFACE_INFO(overlay_depth_only_gpencil_noperspective_iface,
"gp_interp_noperspective")
.no_perspective(Type::VEC2, "thickness")
.no_perspective(Type::FLOAT, "hardness");
GPU_SHADER_CREATE_INFO(overlay_depth_gpencil)
.do_static_compilation(true)
.typedef_source("gpencil_shader_shared.h")
.vertex_out(overlay_depth_only_gpencil_flat_iface)
.vertex_out(overlay_depth_only_gpencil_noperspective_iface)
.vertex_source("overlay_depth_only_gpencil_vert.glsl")
.fragment_source("overlay_depth_only_gpencil_frag.glsl")
.depth_write(DepthWrite::ANY)
.push_constant(Type::BOOL, "gpStrokeOrder3d") /* TODO(fclem): Move to a GPencil object UBO. */
.push_constant(Type::VEC4, "gpDepthPlane") /* TODO(fclem): Move to a GPencil object UBO. */
.additional_info("draw_view",
"draw_modelmat_new",
"draw_resource_handle_new",
"draw_globals",
"draw_gpencil_new",
"draw_object_infos_new");
GPU_SHADER_CREATE_INFO(overlay_depth_pointcloud)
.do_static_compilation(true)
.vertex_source("basic_depth_pointcloud_vert.glsl")

View File

@@ -0,0 +1,57 @@
/* SPDX-FileCopyrightText: 2018-2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_gpencil_lib.glsl)
#pragma BLENDER_REQUIRE(select_lib.glsl)
vec3 ray_plane_intersection(vec3 ray_ori, vec3 ray_dir, vec4 plane)
{
float d = dot(plane.xyz, ray_dir);
vec3 plane_co = plane.xyz * (-plane.w / dot(plane.xyz, plane.xyz));
vec3 h = ray_ori - plane_co;
float lambda = -dot(plane.xyz, h) / ((abs(d) < 1e-8) ? 1e-8 : d);
return ray_ori + ray_dir * lambda;
}
void main()
{
if (gpencil_stroke_round_cap_mask(gp_interp_flat.sspos.xy,
gp_interp_flat.sspos.zw,
gp_interp_flat.aspect,
gp_interp_noperspective.thickness.x,
gp_interp_noperspective.hardness) < 0.001)
{
#ifndef SELECT_ENABLE
/* We cannot discard the fragment in selection mode. Otherwise we would break pipeline
* correctness (no discard if early depth test enforced). */
discard;
#endif
return;
}
#ifndef SELECT_ENABLE
/* We cannot change the fragment's depth in selection mode. Otherwise we would break pipeline
* correctness when early depth test enforced. */
if (!gpStrokeOrder3d) {
/* Stroke order 2D. Project to gpDepthPlane. */
bool is_persp = drw_view.winmat[3][3] == 0.0;
vec2 uvs = vec2(gl_FragCoord.xy) * sizeViewportInv;
vec3 pos_ndc = vec3(uvs, gl_FragCoord.z) * 2.0 - 1.0;
vec4 pos_world = drw_view.viewinv * (drw_view.wininv * vec4(pos_ndc, 1.0));
vec3 pos = pos_world.xyz / pos_world.w;
vec3 ray_ori = pos;
vec3 ray_dir = (is_persp) ? (drw_view.viewinv[3].xyz - pos) : drw_view.viewinv[2].xyz;
vec3 isect = ray_plane_intersection(ray_ori, ray_dir, gpDepthPlane);
vec4 ndc = point_world_to_ndc(isect);
gl_FragDepth = (ndc.z / ndc.w) * 0.5 + 0.5;
}
else {
gl_FragDepth = gl_FragCoord.z;
}
#endif
/* This is optimized to NOP in the non select case. */
select_id_output(select_id);
}

View File

@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: 2022-2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_gpencil_lib.glsl)
#pragma BLENDER_REQUIRE(select_lib.glsl)
void main()
{
vec3 world_pos;
vec3 unused_N;
vec4 unused_color;
float unused_strength;
vec2 unused_uv;
gl_Position = gpencil_vertex(vec4(sizeViewport, sizeViewportInv),
world_pos,
unused_N,
unused_color,
unused_strength,
unused_uv,
gp_interp_flat.sspos,
gp_interp_flat.aspect,
gp_interp_noperspective.thickness,
gp_interp_noperspective.hardness);
/* Small bias to always be on top of the geom. */
gl_Position.z -= 1e-3;
view_clipping_distances(world_pos);
select_id_set(drw_CustomID);
}

View File

@@ -176,10 +176,7 @@ GPU_SHADER_CREATE_INFO(draw_gpencil_new)
.define("gpThicknessIsScreenSpace", "(gpThicknessWorldScale < 0.0)")
/* Per Layer */
.push_constant(Type::FLOAT, "gpThicknessOffset")
.additional_info("draw_modelmat_new",
"draw_resource_id_varying",
"draw_view",
"draw_object_infos_new");
.additional_info("draw_resource_id_varying", "draw_view", "draw_object_infos_new");
/** \} */