Compare commits

...

18 Commits

Author SHA1 Message Date
314ccaa299 Remove recalculations. 2022-07-08 10:45:58 +02:00
fab4b3f463 Use drw_view to retrieve view matrix inverse. 2022-07-08 10:21:57 +02:00
1bba4d0c78 Screen space curvce outline. 2022-07-08 09:59:23 +02:00
546dfd6963 Merge branch 'master' into temp-T95933-object-mode-curve-selection 2022-07-08 07:43:04 +02:00
7306aedca5 Use drw_view.winmat for projection matrix. 2022-07-05 15:16:35 +02:00
3dbe1b0160 Disable show_bounds for curve objects. 2022-07-05 15:09:41 +02:00
ce9b36cb7d Always offset the outline with a single pixel. 2022-07-01 13:26:11 +02:00
1f47e3b49c Viewport size aware. 2022-07-01 13:19:27 +02:00
19c9b05441 Removed hack where thick_time was in world space (shading artifacts). 2022-07-01 09:22:49 +02:00
18c0ec80c9 Merge branch 'master' into temp-T95933-object-mode-curve-selection 2022-07-01 09:02:45 +02:00
3583392fc2 Don't show outlines in sculpt curve mode. 2022-07-01 08:58:23 +02:00
f06af89723 Fix pushing thickness when curve doens't have a thickness. 2022-07-01 08:49:37 +02:00
ce5e1c84df Set a minimum radius for curve rendering. (WIP) 2022-06-28 16:03:56 +02:00
73e4c6e1f3 Try to push radius. 2022-06-28 15:34:34 +02:00
cbd0b7c7d0 Testing. 2022-06-28 13:51:26 +02:00
58abcc1cd4 Add support for clipping planes 2022-06-28 12:10:30 +02:00
555fec7ffd Draw: Add GPU selection for new curve objects. 2022-06-28 12:02:15 +02:00
14b34361bc Draw: Curve outline drawing in object mode.
## TODO

* [ ] drawing curves when performing GPU selection
* [ ] push radius to cover at least one pixel

Differential Revision: https://developer.blender.org/D15308
2022-06-28 10:55:40 +02:00
17 changed files with 213 additions and 19 deletions

View File

@@ -3276,5 +3276,13 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
} }
brush->curves_sculpt_settings->density_add_attempts = 100; brush->curves_sculpt_settings->density_add_attempts = 100;
} }
/* Disable 'show_bounds' option of curve objects. Option was set as there was no object mode
* outline implementation. See T95933. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_CURVES) {
ob->dtx &= ~OB_DRAWBOUNDOX;
}
}
} }
} }

View File

@@ -461,6 +461,7 @@ set(GLSL_SRC
engines/basic/shaders/basic_conservative_depth_geom.glsl engines/basic/shaders/basic_conservative_depth_geom.glsl
engines/basic/shaders/basic_depth_vert.glsl engines/basic/shaders/basic_depth_vert.glsl
engines/basic/shaders/basic_depth_curves_vert.glsl
engines/basic/shaders/basic_depth_pointcloud_vert.glsl engines/basic/shaders/basic_depth_pointcloud_vert.glsl
engines/basic/shaders/basic_depth_frag.glsl engines/basic/shaders/basic_depth_frag.glsl
@@ -538,6 +539,7 @@ set(GLSL_SRC
engines/overlay/shaders/overlay_motion_path_line_vert.glsl engines/overlay/shaders/overlay_motion_path_line_vert.glsl
engines/overlay/shaders/overlay_motion_path_point_vert.glsl engines/overlay/shaders/overlay_motion_path_point_vert.glsl
engines/overlay/shaders/overlay_outline_detect_frag.glsl engines/overlay/shaders/overlay_outline_detect_frag.glsl
engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl
engines/overlay/shaders/overlay_outline_prepass_frag.glsl engines/overlay/shaders/overlay_outline_prepass_frag.glsl
engines/overlay/shaders/overlay_outline_prepass_geom.glsl engines/overlay/shaders/overlay_outline_prepass_geom.glsl
engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl engines/overlay/shaders/overlay_outline_prepass_gpencil_frag.glsl

View File

@@ -53,6 +53,7 @@ typedef struct BASIC_PrivateData {
DRWShadingGroup *depth_shgrp[2]; DRWShadingGroup *depth_shgrp[2];
DRWShadingGroup *depth_shgrp_cull[2]; DRWShadingGroup *depth_shgrp_cull[2];
DRWShadingGroup *depth_hair_shgrp[2]; DRWShadingGroup *depth_hair_shgrp[2];
DRWShadingGroup *depth_curves_shgrp[2];
DRWShadingGroup *depth_pointcloud_shgrp[2]; DRWShadingGroup *depth_pointcloud_shgrp[2];
bool use_material_slot_selection; bool use_material_slot_selection;
} BASIC_PrivateData; /* Transient data */ } BASIC_PrivateData; /* Transient data */
@@ -99,6 +100,9 @@ static void basic_cache_init(void *vedata)
stl->g_data->depth_hair_shgrp[i] = grp = DRW_shgroup_create( stl->g_data->depth_hair_shgrp[i] = grp = DRW_shgroup_create(
BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]); BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]);
stl->g_data->depth_curves_shgrp[i] = grp = DRW_shgroup_create(
BASIC_shaders_curves_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]);
sh = DRW_state_is_select() ? BASIC_shaders_depth_conservative_sh_get(draw_ctx->sh_cfg) : sh = DRW_state_is_select() ? BASIC_shaders_depth_conservative_sh_get(draw_ctx->sh_cfg) :
BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg); BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg);
state |= DRW_STATE_CULL_BACK; state |= DRW_STATE_CULL_BACK;
@@ -156,8 +160,12 @@ static void basic_cache_populate(void *vedata, Object *ob)
basic_cache_populate_particles(vedata, ob); basic_cache_populate_particles(vedata, ob);
} }
/* Make flat object selectable in ortho view if wireframe is enabled. */
const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0; const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if (ob->type == OB_CURVES) {
DRW_shgroup_curves_create_sub(ob, stl->g_data->depth_curves_shgrp[do_in_front], NULL);
}
/* Make flat object selectable in ortho view if wireframe is enabled. */
if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) || if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
(draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) { (draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
int flat_axis = 0; int flat_axis = 0;

View File

@@ -11,6 +11,7 @@ extern "C" {
GPUShader *BASIC_shaders_depth_sh_get(eGPUShaderConfig config); GPUShader *BASIC_shaders_depth_sh_get(eGPUShaderConfig config);
GPUShader *BASIC_shaders_pointcloud_depth_sh_get(eGPUShaderConfig config); GPUShader *BASIC_shaders_pointcloud_depth_sh_get(eGPUShaderConfig config);
GPUShader *BASIC_shaders_curves_depth_sh_get(eGPUShaderConfig config);
GPUShader *BASIC_shaders_depth_conservative_sh_get(eGPUShaderConfig config); GPUShader *BASIC_shaders_depth_conservative_sh_get(eGPUShaderConfig config);
GPUShader *BASIC_shaders_pointcloud_depth_conservative_sh_get(eGPUShaderConfig config); GPUShader *BASIC_shaders_pointcloud_depth_conservative_sh_get(eGPUShaderConfig config);
void BASIC_shaders_free(void); void BASIC_shaders_free(void);

View File

@@ -24,6 +24,7 @@ typedef struct BASIC_Shaders {
/* Depth Pre Pass */ /* Depth Pre Pass */
struct GPUShader *depth; struct GPUShader *depth;
struct GPUShader *pointcloud_depth; struct GPUShader *pointcloud_depth;
struct GPUShader *curves_depth;
struct GPUShader *depth_conservative; struct GPUShader *depth_conservative;
struct GPUShader *pointcloud_depth_conservative; struct GPUShader *pointcloud_depth_conservative;
} BASIC_Shaders; } BASIC_Shaders;
@@ -53,6 +54,16 @@ GPUShader *BASIC_shaders_pointcloud_depth_sh_get(eGPUShaderConfig config)
return sh_data->pointcloud_depth; return sh_data->pointcloud_depth;
} }
GPUShader *BASIC_shaders_curves_depth_sh_get(eGPUShaderConfig config)
{
BASIC_Shaders *sh_data = &e_data.sh_data[config];
if (sh_data->curves_depth == NULL) {
sh_data->curves_depth = GPU_shader_create_from_info_name(
config == GPU_SHADER_CFG_CLIPPED ? "basic_depth_curves_clipped" : "basic_depth_curves");
}
return sh_data->curves_depth;
}
GPUShader *BASIC_shaders_depth_conservative_sh_get(eGPUShaderConfig config) GPUShader *BASIC_shaders_depth_conservative_sh_get(eGPUShaderConfig config)
{ {
BASIC_Shaders *sh_data = &e_data.sh_data[config]; BASIC_Shaders *sh_data = &e_data.sh_data[config];

View File

@@ -0,0 +1,27 @@
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
void main()
{
GPU_INTEL_VERTEX_SHADER_WORKAROUND
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
float time, thick_time, thickness;
vec3 world_pos, tan, binor;
hair_get_pos_tan_binor_time(is_persp,
ModelMatrixInverse,
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
world_pos,
tan,
binor,
time,
thickness,
thick_time);
gl_Position = point_world_to_ndc(world_pos);
view_clipping_distances(world_pos);
}

View File

@@ -27,6 +27,9 @@ GPU_SHADER_CREATE_INFO(basic_pointcloud)
.vertex_source("basic_depth_pointcloud_vert.glsl") .vertex_source("basic_depth_pointcloud_vert.glsl")
.additional_info("draw_pointcloud"); .additional_info("draw_pointcloud");
GPU_SHADER_CREATE_INFO(basic_curves)
.vertex_source("basic_depth_curves_vert.glsl")
.additional_info("draw_hair");
/** \} */ /** \} */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@@ -46,7 +49,8 @@ GPU_SHADER_CREATE_INFO(basic_pointcloud)
#define BASIC_OBTYPE_VARIATIONS(prefix, ...) \ #define BASIC_OBTYPE_VARIATIONS(prefix, ...) \
BASIC_CONSERVATIVE_VARIATIONS(prefix##_mesh, "basic_mesh", __VA_ARGS__) \ BASIC_CONSERVATIVE_VARIATIONS(prefix##_mesh, "basic_mesh", __VA_ARGS__) \
BASIC_CONSERVATIVE_VARIATIONS(prefix##_pointcloud, "basic_pointcloud", __VA_ARGS__) BASIC_CONSERVATIVE_VARIATIONS(prefix##_pointcloud, "basic_pointcloud", __VA_ARGS__) \
BASIC_CLIPPING_VARIATIONS(prefix##_curves, "basic_curves", __VA_ARGS__)
/** \} */ /** \} */

View File

@@ -310,6 +310,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
(pd->ctx_mode == CTX_MODE_PARTICLE); (pd->ctx_mode == CTX_MODE_PARTICLE);
const bool in_paint_mode = (ob == draw_ctx->obact) && const bool in_paint_mode = (ob == draw_ctx->obact) &&
(draw_ctx->object_mode & OB_MODE_ALL_PAINT); (draw_ctx->object_mode & OB_MODE_ALL_PAINT);
const bool in_sculpt_curve_mode = (ob == draw_ctx->obact) &&
(draw_ctx->object_mode & OB_MODE_SCULPT_CURVES);
const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != NULL) && const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != NULL) &&
(ob->sculpt->mode_type == OB_MODE_SCULPT); (ob->sculpt->mode_type == OB_MODE_SCULPT);
const bool in_curves_sculpt_mode = (ob == draw_ctx->obact) && const bool in_curves_sculpt_mode = (ob == draw_ctx->obact) &&
@@ -333,8 +335,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0; const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0;
const bool draw_wires = draw_surface && has_surface && const bool draw_wires = draw_surface && has_surface &&
(pd->wireframe_mode || !pd->hide_overlays); (pd->wireframe_mode || !pd->hide_overlays);
const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable && has_surface && const bool draw_outlines = !in_edit_mode && !in_paint_mode && !in_sculpt_curve_mode &&
!instance_parent_in_edit_mode && renderable && has_surface && !instance_parent_in_edit_mode &&
(pd->v3d_flag & V3D_SELECT_OUTLINE) && (pd->v3d_flag & V3D_SELECT_OUTLINE) &&
(ob->base_flag & BASE_SELECTED); (ob->base_flag & BASE_SELECTED);
const bool draw_bone_selection = (ob->type == OB_MESH) && pd->armature.do_pose_fade_geom && const bool draw_bone_selection = (ob->type == OB_MESH) && pd->armature.do_pose_fade_geom &&

View File

@@ -133,6 +133,10 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps); pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0); DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0); DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0);
GPUShader *sh_curves = OVERLAY_shader_outline_prepass_curves();
pd->outlines_curves_grp = grp = DRW_shgroup_create(sh_curves, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
} }
/* outlines_prepass_ps is still needed for selection of probes. */ /* outlines_prepass_ps is still needed for selection of probes. */
@@ -267,6 +271,12 @@ static void OVERLAY_outline_volume(OVERLAY_PrivateData *pd, Object *ob)
DRW_shgroup_call(shgroup, geom, ob); DRW_shgroup_call(shgroup, geom, ob);
} }
static void OVERLAY_outline_curves(OVERLAY_PrivateData *pd, Object *ob)
{
DRWShadingGroup *shgroup = pd->outlines_curves_grp;
DRW_shgroup_curves_create_sub(ob, shgroup, NULL);
}
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata, void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
Object *ob, Object *ob,
OVERLAY_DupliData *dupli, OVERLAY_DupliData *dupli,
@@ -293,6 +303,11 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return; return;
} }
if (ob->type == OB_CURVES) {
OVERLAY_outline_curves(pd, ob);
return;
}
if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) { if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
/* Looks bad in this case. Could be relaxed if we draw a /* Looks bad in this case. Could be relaxed if we draw a
* wireframe of some sort in the future. */ * wireframe of some sort in the future. */

View File

@@ -268,6 +268,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *motion_path_lines_grp; DRWShadingGroup *motion_path_lines_grp;
DRWShadingGroup *motion_path_points_grp; DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp; DRWShadingGroup *outlines_grp;
DRWShadingGroup *outlines_curves_grp;
DRWShadingGroup *outlines_ptcloud_grp; DRWShadingGroup *outlines_ptcloud_grp;
DRWShadingGroup *outlines_gpencil_grp; DRWShadingGroup *outlines_gpencil_grp;
DRWShadingGroup *paint_depth_grp; DRWShadingGroup *paint_depth_grp;
@@ -743,6 +744,7 @@ GPUShader *OVERLAY_shader_motion_path_line(void);
GPUShader *OVERLAY_shader_motion_path_vert(void); GPUShader *OVERLAY_shader_motion_path_vert(void);
GPUShader *OVERLAY_shader_uniform_color(void); GPUShader *OVERLAY_shader_uniform_color(void);
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire); GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
GPUShader *OVERLAY_shader_outline_prepass_curves(void);
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void); GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void); GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
GPUShader *OVERLAY_shader_extra_grid(void); GPUShader *OVERLAY_shader_extra_grid(void);

View File

@@ -76,6 +76,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *motion_path_line; GPUShader *motion_path_line;
GPUShader *motion_path_vert; GPUShader *motion_path_vert;
GPUShader *outline_prepass; GPUShader *outline_prepass;
GPUShader *outline_prepass_curves;
GPUShader *outline_prepass_gpencil; GPUShader *outline_prepass_gpencil;
GPUShader *outline_prepass_pointcloud; GPUShader *outline_prepass_pointcloud;
GPUShader *outline_prepass_wire; GPUShader *outline_prepass_wire;
@@ -651,6 +652,18 @@ GPUShader *OVERLAY_shader_outline_prepass(bool use_wire)
return use_wire ? sh_data->outline_prepass_wire : sh_data->outline_prepass; return use_wire ? sh_data->outline_prepass_wire : sh_data->outline_prepass;
} }
GPUShader *OVERLAY_shader_outline_prepass_curves()
{
const DRWContextState *draw_ctx = DRW_context_state_get();
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->outline_prepass_curves) {
sh_data->outline_prepass_curves = GPU_shader_create_from_info_name(
draw_ctx->sh_cfg ? "overlay_outline_prepass_curves_clipped" :
"overlay_outline_prepass_curves");
}
return sh_data->outline_prepass_curves;
}
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void) GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
{ {
const DRWContextState *draw_ctx = DRW_context_state_get(); const DRWContextState *draw_ctx = DRW_context_state_get();

View File

@@ -29,6 +29,16 @@ GPU_SHADER_CREATE_INFO(overlay_outline_prepass_mesh_clipped)
GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_wire_iface, "vert").flat(Type::VEC3, "pos"); GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_wire_iface, "vert").flat(Type::VEC3, "pos");
GPU_SHADER_CREATE_INFO(overlay_outline_prepass_curves)
.do_static_compilation(true)
.vertex_source("overlay_outline_prepass_curves_vert.glsl")
.additional_info("draw_hair", "overlay_outline_prepass")
.additional_info("draw_object_infos");
GPU_SHADER_CREATE_INFO(overlay_outline_prepass_curves_clipped)
.do_static_compilation(true)
.additional_info("overlay_outline_prepass_curves", "drw_clipped");
GPU_SHADER_CREATE_INFO(overlay_outline_prepass_wire) GPU_SHADER_CREATE_INFO(overlay_outline_prepass_wire)
.do_static_compilation(true) .do_static_compilation(true)
.define("USE_GEOM") .define("USE_GEOM")

View File

@@ -0,0 +1,81 @@
#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
uint outline_colorid_get(void)
{
int flag = int(abs(ObjectInfo.w));
bool is_active = (flag & DRW_BASE_ACTIVE) != 0;
if (isTransform) {
return 0u; /* colorTransform */
}
else if (is_active) {
return 3u; /* colorActive */
}
else {
return 1u; /* colorSelect */
}
return 0u;
}
/* Replace top 2 bits (of the 16bit output) by outlineId.
* This leaves 16K different IDs to create outlines between objects.
vec3 world_pos = point_object_to_world(pos);
* SHIFT = (32 - (16 - 2)) */
#define SHIFT 18u
void main()
{
bool is_persp = (drw_view.winmat[3][3] == 0.0);
float time, thickness;
vec3 center_wpos, tan, binor;
hair_get_center_pos_tan_binor_time(is_persp,
ModelMatrixInverse,
drw_view.viewinv[3].xyz,
drw_view.viewinv[2].xyz,
center_wpos,
tan,
binor,
time,
thickness);
vec3 world_pos;
if (hairThicknessRes > 1) {
/* Calculate the thickness, thicktime, worldpos taken into account the outline. */
float outline_width = point_world_to_ndc(center_wpos).w * 1.25 *
drw_view.viewport_size_inverse.y * drw_view.wininv[1][1];
thickness += outline_width;
float thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1);
thick_time = thickness * (thick_time * 2.0 - 1.0);
/* Take object scale into account.
* NOTE: This only works fine with uniform scaling. */
float scale = 1.0 / length(mat3(ModelMatrixInverse) * binor);
world_pos = center_wpos + binor * thick_time * scale;
}
else {
world_pos = center_wpos;
}
gl_Position = point_world_to_ndc(world_pos);
#ifdef USE_GEOM
vert.pos = point_world_to_view(world_pos);
#endif
/* Small bias to always be on top of the geom. */
gl_Position.z -= 1e-3;
/* ID 0 is nothing (background) */
interp.ob_id = uint(resource_handle + 1);
/* Should be 2 bits only [0..3]. */
uint outline_id = outline_colorid_get();
/* Combine for 16bit uint target. */
interp.ob_id = (outline_id << 14u) | ((interp.ob_id << SHIFT) >> SHIFT);
view_clipping_distances(world_pos);
}

View File

@@ -164,16 +164,15 @@ float hair_shaperadius(float shape, float root, float tip, float time)
in float dummy; in float dummy;
# endif # endif
void hair_get_pos_tan_binor_time(bool is_persp, void hair_get_center_pos_tan_binor_time(bool is_persp,
mat4 invmodel_mat, mat4 invmodel_mat,
vec3 camera_pos, vec3 camera_pos,
vec3 camera_z, vec3 camera_z,
out vec3 wpos, out vec3 wpos,
out vec3 wtan, out vec3 wtan,
out vec3 wbinor, out vec3 wbinor,
out float time, out float time,
out float thickness, out float thickness)
out float thick_time)
{ {
int id = hair_get_base_id(); int id = hair_get_base_id();
vec4 data = texelFetch(hairPointBuffer, id); vec4 data = texelFetch(hairPointBuffer, id);
@@ -202,15 +201,27 @@ void hair_get_pos_tan_binor_time(bool is_persp,
wbinor = normalize(cross(camera_vec, wtan)); wbinor = normalize(cross(camera_vec, wtan));
thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time); thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time);
}
void hair_get_pos_tan_binor_time(bool is_persp,
mat4 invmodel_mat,
vec3 camera_pos,
vec3 camera_z,
out vec3 wpos,
out vec3 wtan,
out vec3 wbinor,
out float time,
out float thickness,
out float thick_time)
{
hair_get_center_pos_tan_binor_time(
is_persp, invmodel_mat, camera_pos, camera_z, wpos, wtan, wbinor, time, thickness);
if (hairThicknessRes > 1) { if (hairThicknessRes > 1) {
thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1); thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1);
thick_time = thickness * (thick_time * 2.0 - 1.0); thick_time = thickness * (thick_time * 2.0 - 1.0);
/* Take object scale into account. /* Take object scale into account.
* NOTE: This only works fine with uniform scaling. */ * NOTE: This only works fine with uniform scaling. */
float scale = 1.0 / length(mat3(invmodel_mat) * wbinor); float scale = 1.0 / length(mat3(invmodel_mat) * wbinor);
wpos += wbinor * thick_time * scale; wpos += wbinor * thick_time * scale;
} }
else { else {

View File

@@ -256,6 +256,7 @@ static void test_overlay_glsl_shaders()
EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr); EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass_curves(), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass_gpencil(), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass_gpencil(), nullptr);
EXPECT_NE(OVERLAY_shader_outline_prepass_pointcloud(), nullptr); EXPECT_NE(OVERLAY_shader_outline_prepass_pointcloud(), nullptr);
EXPECT_NE(OVERLAY_shader_extra_grid(), nullptr); EXPECT_NE(OVERLAY_shader_extra_grid(), nullptr);
@@ -398,6 +399,7 @@ static void test_basic_glsl_shaders()
eGPUShaderConfig sh_cfg = static_cast<eGPUShaderConfig>(i); eGPUShaderConfig sh_cfg = static_cast<eGPUShaderConfig>(i);
BASIC_shaders_depth_sh_get(sh_cfg); BASIC_shaders_depth_sh_get(sh_cfg);
BASIC_shaders_pointcloud_depth_sh_get(sh_cfg); BASIC_shaders_pointcloud_depth_sh_get(sh_cfg);
BASIC_shaders_curves_depth_sh_get(sh_cfg);
BASIC_shaders_depth_conservative_sh_get(sh_cfg); BASIC_shaders_depth_conservative_sh_get(sh_cfg);
BASIC_shaders_pointcloud_depth_conservative_sh_get(sh_cfg); BASIC_shaders_pointcloud_depth_conservative_sh_get(sh_cfg);
} }

View File

@@ -465,7 +465,6 @@ static int curves_convert_from_particle_system_exec(bContext *C, wmOperator *UNU
} }
Object *ob_new = BKE_object_add(&bmain, &view_layer, OB_CURVES, psys_eval->name); Object *ob_new = BKE_object_add(&bmain, &view_layer, OB_CURVES, psys_eval->name);
ob_new->dtx |= OB_DRAWBOUNDOX; /* TODO: Remove once there is actual drawing. */
Curves *curves_id = static_cast<Curves *>(ob_new->data); Curves *curves_id = static_cast<Curves *>(ob_new->data);
BKE_object_apply_mat4(ob_new, ob_from_orig->obmat, true, false); BKE_object_apply_mat4(ob_new, ob_from_orig->obmat, true, false);
bke::CurvesGeometry::wrap(curves_id->geometry) = particles_to_curves(*ob_from_eval, *psys_eval); bke::CurvesGeometry::wrap(curves_id->geometry) = particles_to_curves(*ob_from_eval, *psys_eval);

View File

@@ -2044,7 +2044,6 @@ static int object_curves_random_add_exec(bContext *C, wmOperator *op)
} }
Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits); Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits);
object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */
Curves *curves_id = static_cast<Curves *>(object->data); Curves *curves_id = static_cast<Curves *>(object->data);
bke::CurvesGeometry::wrap(curves_id->geometry) = ed::curves::primitive_random_sphere(500, 8); bke::CurvesGeometry::wrap(curves_id->geometry) = ed::curves::primitive_random_sphere(500, 8);
@@ -2081,7 +2080,6 @@ static int object_curves_empty_hair_add_exec(bContext *C, wmOperator *op)
Object *surface_ob = CTX_data_active_object(C); Object *surface_ob = CTX_data_active_object(C);
Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits); Object *object = ED_object_add_type(C, OB_CURVES, nullptr, loc, rot, false, local_view_bits);
object->dtx |= OB_DRAWBOUNDOX; /* TODO: remove once there is actual drawing. */
if (surface_ob != nullptr && surface_ob->type == OB_MESH) { if (surface_ob != nullptr && surface_ob->type == OB_MESH) {
Curves *curves_id = static_cast<Curves *>(object->data); Curves *curves_id = static_cast<Curves *>(object->data);