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:
committed by
Clément Foucault
parent
a0f653c002
commit
a4cd59e369
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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_ = ⊂
|
||||
}
|
||||
{
|
||||
auto &sub = ps_.sub("GreasePencil");
|
||||
sub.shader_set(res.shaders.depth_grease_pencil.get());
|
||||
sub.bind_ubo("globalsBlock", &res.globals_buf);
|
||||
grease_pencil_ps_ = ⊂
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user