diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-01-11 21:35:56 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-01-11 21:35:56 +0300 |
commit | da97b6930b47555fbc526b7165d5b73abe06252d (patch) | |
tree | 023f37711a9be4ed523f31831966ba5558b094c4 | |
parent | 31782609f457b97d99912503a16f3176a3d4aec0 (diff) |
DRW: Fix T53583 Armature instances not drawing.
Was due to the fact that the instances don't have a "static" obmat that can be referenced to use as a uniform.
Solution : precompute the full matrix for each bone and pass it as instance data. (theses are copied into a buffer and can be discarded right away)
Note: this could be optimized further and make only one drawcall (shgroup) to draw all bone instance of one type (vs. one call per armature).
6 files changed, 69 insertions, 63 deletions
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index c7a88f7689e..09fe3d68651 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -102,20 +102,22 @@ static void drw_shgroup_bone_octahedral_solid(const float (*bone_mat)[4], const { if (g_data.bone_octahedral_solid == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_octahedral_get(); - g_data.bone_octahedral_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat); + g_data.bone_octahedral_solid = shgroup_instance_solid(g_data.pass_bone_solid, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_solid, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_solid, final_bonemat, color); } static void drw_shgroup_bone_octahedral_wire(const float (*bone_mat)[4], const float color[4]) { if (g_data.bone_octahedral_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_octahedral_wire_outline_get(); - g_data.bone_octahedral_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_octahedral_wire = shgroup_instance_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_wire, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_octahedral_wire, final_bonemat, color); } /* Box / B-Bone */ @@ -123,20 +125,22 @@ static void drw_shgroup_bone_box_solid(const float (*bone_mat)[4], const float c { if (g_data.bone_box_solid == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_box_get(); - g_data.bone_box_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat); + g_data.bone_box_solid = shgroup_instance_solid(g_data.pass_bone_solid, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_box_solid, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_box_solid, final_bonemat, color); } static void drw_shgroup_bone_box_wire(const float (*bone_mat)[4], const float color[4]) { if (g_data.bone_box_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_box_wire_outline_get(); - g_data.bone_box_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_box_wire = shgroup_instance_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_box_wire, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_box_wire, final_bonemat, color); } /* Wire */ @@ -144,10 +148,11 @@ static void drw_shgroup_bone_wire_wire(const float (*bone_mat)[4], const float c { if (g_data.bone_wire_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_wire_wire_outline_get(); - g_data.bone_wire_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_wire_wire = shgroup_instance_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_wire_wire, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_wire_wire, final_bonemat, color); } /* Envelope */ @@ -159,10 +164,11 @@ static void drw_shgroup_bone_envelope_distance( if (g_data.bone_envelope_distance == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_envelope_distance_outline_get(); /* Note: bone_wire draw pass is not really working, think we need another one here? */ - g_data.bone_envelope_distance = shgroup_instance_bone_envelope_wire(g_data.pass_bone_envelope, geom, g_data.ob->obmat); + g_data.bone_envelope_distance = shgroup_instance_bone_envelope_wire(g_data.pass_bone_envelope, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_envelope_distance, bone_mat, color, radius_head, radius_tail, distance); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_envelope_distance, final_bonemat, color, radius_head, radius_tail, distance); } } @@ -172,10 +178,11 @@ static void drw_shgroup_bone_envelope_solid( { if (g_data.bone_envelope_solid == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_envelope_solid_get(); - g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat); + g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.pass_bone_solid, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_envelope_solid, bone_mat, color, radius_head, radius_tail); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_envelope_solid, final_bonemat, color, radius_head, radius_tail); } static void drw_shgroup_bone_envelope_wire( @@ -184,10 +191,11 @@ static void drw_shgroup_bone_envelope_wire( { if (g_data.bone_envelope_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_envelope_wire_outline_get(); - g_data.bone_envelope_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_envelope_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_envelope_wire, bone_mat, color, radius_head, radius_tail, distance); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_envelope_wire, final_bonemat, color, radius_head, radius_tail, distance); } static void drw_shgroup_bone_envelope_head_wire( @@ -196,10 +204,11 @@ static void drw_shgroup_bone_envelope_head_wire( { if (g_data.bone_envelope_head_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_envelope_head_wire_outline_get(); - g_data.bone_envelope_head_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_envelope_head_wire = shgroup_instance_bone_envelope_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_envelope_head_wire, bone_mat, color, radius_head, radius_tail, distance); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_envelope_head_wire, final_bonemat, color, radius_head, radius_tail, distance); } /* Custom (geometry) */ @@ -209,8 +218,10 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4], const floa /* grr, not re-using instances! */ struct Gwn_Batch *geom = DRW_cache_object_surface_get(custom); if (geom) { - DRWShadingGroup *shgrp_geom_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat); - DRW_shgroup_call_dynamic_add(shgrp_geom_solid, bone_mat, color); + DRWShadingGroup *shgrp_geom_solid = shgroup_instance_solid(g_data.pass_bone_solid, geom); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, color); } } @@ -219,8 +230,10 @@ static void drw_shgroup_bone_custom_wire(const float (*bone_mat)[4], const float /* grr, not re-using instances! */ struct Gwn_Batch *geom = DRW_cache_object_wire_outline_get(custom); if (geom) { - DRWShadingGroup *shgrp_geom_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); - DRW_shgroup_call_dynamic_add(shgrp_geom_wire, bone_mat, color); + DRWShadingGroup *shgrp_geom_wire = shgroup_instance_wire(g_data.pass_bone_wire, geom); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, color); } } @@ -229,20 +242,22 @@ static void drw_shgroup_bone_point_solid(const float (*bone_mat)[4], const float { if (g_data.bone_point_solid == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_point_get(); - g_data.bone_point_solid = shgroup_instance_objspace_solid(g_data.pass_bone_solid, geom, g_data.ob->obmat); + g_data.bone_point_solid = shgroup_instance_solid(g_data.pass_bone_solid, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_point_solid, final_bonemat, color); } static void drw_shgroup_bone_point_wire(const float (*bone_mat)[4], const float color[4]) { if (g_data.bone_point_wire == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_point_wire_outline_get(); - g_data.bone_point_wire = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_point_wire = shgroup_instance_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_point_wire, final_bonemat, color); } /* Axes */ @@ -250,10 +265,11 @@ static void drw_shgroup_bone_axes(const float (*bone_mat)[4], const float color[ { if (g_data.bone_axes == NULL) { struct Gwn_Batch *geom = DRW_cache_bone_arrows_get(); - g_data.bone_axes = shgroup_instance_objspace_wire(g_data.pass_bone_wire, geom, g_data.ob->obmat); + g_data.bone_axes = shgroup_instance_wire(g_data.pass_bone_wire, geom); } - - DRW_shgroup_call_dynamic_add(g_data.bone_axes, bone_mat, color); + float final_bonemat[4][4]; + mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); + DRW_shgroup_call_dynamic_add(g_data.bone_axes, final_bonemat, color); } /* Relationship lines */ diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index e86a231c19d..0eb97a54ba5 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -215,7 +215,7 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *g return grp; } -DRWShadingGroup *shgroup_instance_objspace_solid(DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]) +DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom) { static float light[3] = {0.0f, 0.0f, 1.0f}; GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR); @@ -223,20 +223,18 @@ DRWShadingGroup *shgroup_instance_objspace_solid(DRWPass *pass, struct Gwn_Batch DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); DRW_shgroup_attrib_float(grp, "color", 4); - DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat); DRW_shgroup_uniform_vec3(grp, "light", light, 1); return grp; } -DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]) +DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR); DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); DRW_shgroup_attrib_float(grp, "color", 4); - DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat); return grp; } @@ -336,7 +334,7 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]) +DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Gwn_Batch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE); @@ -346,12 +344,11 @@ DRWShadingGroup *shgroup_instance_bone_envelope_wire(DRWPass *pass, struct Gwn_B DRW_shgroup_attrib_float(grp, "radius_head", 1); DRW_shgroup_attrib_float(grp, "radius_tail", 1); DRW_shgroup_attrib_float(grp, "distance", 1); - DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat); return grp; } -DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]) +DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_Batch *geom) { static float light[3] = {0.0f, 0.0f, 1.0f}; GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID); @@ -361,7 +358,6 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_ DRW_shgroup_attrib_float(grp, "color", 4); DRW_shgroup_attrib_float(grp, "radius_head", 1); DRW_shgroup_attrib_float(grp, "radius_tail", 1); - DRW_shgroup_uniform_mat4(grp, "ObjectModelMatrix", (float *)obmat); DRW_shgroup_uniform_vec3(grp, "light", light, 1); return grp; diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 0a7227287ea..cfd88effd15 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -106,8 +106,8 @@ struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, fl struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, float color[4]); struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, float color[4]); struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Gwn_Batch *geom, float *size); -struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]); -struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]); +struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct Gwn_Batch *geom); @@ -116,8 +116,8 @@ struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Gwn_Batch struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]); -struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]); +struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Gwn_Batch *geom); struct DRWShadingGroup *shgroup_instance_mball_helpers(struct DRWPass *pass, struct Gwn_Batch *geom); int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color); diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl index 74c8f6f3103..d0f2a8dcd51 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl @@ -7,7 +7,6 @@ uniform mat4 ViewMatrix; -uniform mat4 ObjectModelMatrix; uniform mat4 ViewProjectionMatrix; @@ -38,7 +37,7 @@ void main() bone_mat[1] = normalize(bone_mat[1]); bone_mat[2] = normalize(bone_mat[2]); - mat3 nor_mat = transpose(inverse(mat3(ViewMatrix * ObjectModelMatrix) * bone_mat)); + mat3 nor_mat = transpose(inverse(mat3(ViewMatrix) * bone_mat)); /* Where does this comes from???? Don't know why, but is mandatory anyway... :/ */ const float size = 2.0f; @@ -116,7 +115,7 @@ void main() ob_pos.xyz = bone_mat * ob_pos.xyz; ob_pos.w = 1.0f; - gl_Position = ViewProjectionMatrix * ObjectModelMatrix * (ob_pos + ob_bone_origin); + gl_Position = ViewProjectionMatrix * (ob_pos + ob_bone_origin); normal = normalize(nor_mat * nor); finalColor = color; } diff --git a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl index a36eb1dec77..1bdad924bd2 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl @@ -7,11 +7,8 @@ * Note that if one of head/tail radius is negative, it assumes it only works on the other end of the bone * (used to draw head/tail spheres). */ - uniform mat4 ViewMatrix; uniform mat4 ProjectionMatrix; -uniform mat4 ObjectModelMatrix; - /* ---- Instanciated Attribs ---- */ in vec4 pos; /* z encodes head (== 0.0f), tail (== 1.0f) or in-between; w encodes inner (0.0f) or outer border. */ @@ -36,7 +33,7 @@ void main() vec4 tail = bone_mat * vec4(0.0f, 1.0f, 0.0f, 1.0f); /* We generate our XY axes in object space, Y axis being aligned with bone in view space. */ - mat4 obview_mat = ViewMatrix * ObjectModelMatrix; + mat4 obview_mat = ViewMatrix; mat4 iobview_mat = inverse(obview_mat); vec4 view_bone_vec = obview_mat * normalize(tail - head); diff --git a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl index 195d4849d99..9876717b297 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl @@ -1,7 +1,6 @@ uniform mat4 ViewMatrix; uniform mat4 ViewProjectionMatrix; -uniform mat4 ObjectModelMatrix; /* ---- Instanciated Attribs ---- */ in vec3 pos; @@ -16,11 +15,10 @@ flat out vec4 finalColor; void main() { - mat4 FinalModelMatrix = ObjectModelMatrix * InstanceModelMatrix; - mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * FinalModelMatrix; + mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * InstanceModelMatrix; /* This is slow and run per vertex, but it's still faster than * doing it per instance on CPU and sending it on via instance attrib */ - mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * FinalModelMatrix))); + mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix))); gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); normal = NormalMatrix * nor; |