Skip to content

Commit

Permalink
Option for software skinning in MeshInstance
Browse files Browse the repository at this point in the history
Option in MeshInstance to enable software skinning, in order to test
against the current USE_SKELETON_SOFTWARE path which causes problems
with bad performance.

Co-authored-by: lawnjelly <[email protected]>
  • Loading branch information
pouleyKetchoupp and lawnjelly committed Oct 8, 2020
1 parent 4040cd3 commit f954471
Show file tree
Hide file tree
Showing 15 changed files with 589 additions and 8 deletions.
13 changes: 13 additions & 0 deletions doc/classes/MeshInstance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@
This helper creates a [StaticBody] child node with a [ConcavePolygonShape] collision shape calculated from the mesh geometry. It's mainly used for testing.
</description>
</method>
<method name="get_active_material" qualifiers="const">
<return type="Material">
</return>
<argument index="0" name="surface" type="int">
</argument>
<description>
Returns the [Material] that will be used by the [Mesh] when drawing. This can return the [member GeometryInstance.material_override], the surface override [Material] defined in this [MeshInstance], or the surface [Material] defined in the [Mesh]. For example, if [member GeometryInstance.material_override] is used, all surfaces will return the override material.
</description>
</method>
<method name="get_surface_material" qualifiers="const">
<return type="Material">
</return>
Expand Down Expand Up @@ -68,6 +77,10 @@
<member name="skin" type="Skin" setter="set_skin" getter="get_skin">
Sets the skin to be used by this instance.
</member>
<member name="software_skinning_transform_normals" type="bool" setter="set_software_skinning_transform_normals" getter="is_software_skinning_transform_normals_enabled" default="true">
If [code]true[/code], normals are transformed when software skinning is used. Set to [code]false[/code] when normals are not needed for better performance.
See [member ProjectSettings.rendering/quality/skinning/software_skinning_fallback] for details about how software skinning is enabled.
</member>
</members>
<constants>
</constants>
Expand Down
10 changes: 10 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,16 @@
<member name="rendering/quality/shadows/filter_mode.mobile" type="int" setter="" getter="" default="0">
Lower-end override for [member rendering/quality/shadows/filter_mode] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/skinning/software_skinning_fallback" type="bool" setter="" getter="" default="true">
Allows [MeshInstance] to perform skinning on the CPU when the hardware doesn't support the default GPU skinning process with GLES2.
If [code]false[/code], an alternative skinning process on the GPU is used in this case (slower in most cases).
See also [member rendering/quality/skinning/force_software_skinning].
[b]Note:[/b] When the software skinning fallback is triggered, custom vertex shaders will behave in a different way, because the bone transform will be already applied to the modelview matrix.
</member>
<member name="rendering/quality/skinning/force_software_skinning" type="bool" setter="" getter="" default="false">
Forces [MeshInstance] to always perform skinning on the CPU (applies to both GLES2 and GLES3).
See also [member rendering/quality/skinning/software_skinning_fallback].
</member>
<member name="rendering/quality/spatial_partitioning/render_tree_balance" type="float" setter="" getter="" default="0.17">
The rendering octree balance can be changed to favor smaller ([code]0[/code]), or larger ([code]1[/code]) branches.
Larger branches can increase performance significantly in some projects.
Expand Down
3 changes: 2 additions & 1 deletion doc/classes/VisualServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1679,7 +1679,8 @@
<argument index="0" name="feature" type="String">
</argument>
<description>
Returns [code]true[/code] if the OS supports a certain feature. Features might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code] and [code]pvrtc[/code].
Returns [code]true[/code] if the OS supports a certain feature. Features might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code], [code]pvrtc[/code] and [code]skinning_fallback[/code].
When rendering with GLES2, returns [code]true[/code] with [code]skinning_fallback[/code] in case the hardware doesn't support the default GPU skinning process.
</description>
</method>
<method name="immediate_begin">
Expand Down
42 changes: 42 additions & 0 deletions drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,8 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_depth_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.uses_tangent = false;
p_shader->spatial.uses_ensure_correct_normals = false;
p_shader->spatial.writes_modelview_or_projection = false;
p_shader->spatial.uses_world_coordinates = false;

Expand All @@ -1497,6 +1499,8 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {

shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;

shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;

shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;

Expand All @@ -1506,6 +1510,11 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;

// Use of any of these BUILTINS indicate the need for transformed tangents.
// This is needed to know when to transform tangents in software skinning.
shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;

shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
Expand Down Expand Up @@ -1897,6 +1906,36 @@ bool RasterizerStorageGLES2::material_casts_shadows(RID p_material) {
return casts_shadows;
}

bool RasterizerStorageGLES2::material_uses_tangents(RID p_material) {
Material *material = material_owner.get(p_material);
ERR_FAIL_COND_V(!material, false);

if (!material->shader) {
return false;
}

if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}

return material->shader->spatial.uses_tangent;
}

bool RasterizerStorageGLES2::material_uses_ensure_correct_normals(RID p_material) {
Material *material = material_owner.get(p_material);
ERR_FAIL_COND_V(!material, false);

if (!material->shader) {
return false;
}

if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}

return material->shader->spatial.uses_ensure_correct_normals;
}

void RasterizerStorageGLES2::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) {

Material *material = material_owner.getornull(p_material);
Expand Down Expand Up @@ -5769,6 +5808,9 @@ bool RasterizerStorageGLES2::has_os_feature(const String &p_feature) const {
if (p_feature == "etc")
return config.etc1_supported;

if (p_feature == "skinning_fallback")
return config.use_skeleton_software;

return false;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/gles2/rasterizer_storage_gles2.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
bool uses_screen_texture;
bool uses_depth_texture;
bool uses_time;
bool uses_tangent;
bool uses_ensure_correct_normals;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
bool uses_world_coordinates;
Expand Down Expand Up @@ -607,6 +609,8 @@ class RasterizerStorageGLES2 : public RasterizerStorage {

virtual bool material_is_animated(RID p_material);
virtual bool material_casts_shadows(RID p_material);
virtual bool material_uses_tangents(RID p_material);
virtual bool material_uses_ensure_correct_normals(RID p_material);

virtual void material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
virtual void material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
Expand Down
39 changes: 39 additions & 0 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2342,6 +2342,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_depth_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.uses_tangent = false;
p_shader->spatial.uses_ensure_correct_normals = false;
p_shader->spatial.writes_modelview_or_projection = false;
p_shader->spatial.uses_world_coordinates = false;

Expand All @@ -2366,6 +2368,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {

shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;

shaders.actions_scene.render_mode_flags["ensure_correct_normals"] = &p_shader->spatial.uses_ensure_correct_normals;

shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;

Expand All @@ -2375,6 +2379,11 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.usage_flag_pointers["DEPTH_TEXTURE"] = &p_shader->spatial.uses_depth_texture;
shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time;

// Use of any of these BUILTINS indicate the need for transformed tangents.
// This is needed to know when to transform tangents in software skinning.
shaders.actions_scene.usage_flag_pointers["TANGENT"] = &p_shader->spatial.uses_tangent;
shaders.actions_scene.usage_flag_pointers["NORMALMAP"] = &p_shader->spatial.uses_tangent;

shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
Expand Down Expand Up @@ -2726,6 +2735,36 @@ bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) {
return casts_shadows;
}

bool RasterizerStorageGLES3::material_uses_tangents(RID p_material) {
Material *material = material_owner.get(p_material);
ERR_FAIL_COND_V(!material, false);

if (!material->shader) {
return false;
}

if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}

return material->shader->spatial.uses_tangent;
}

bool RasterizerStorageGLES3::material_uses_ensure_correct_normals(RID p_material) {
Material *material = material_owner.get(p_material);
ERR_FAIL_COND_V(!material, false);

if (!material->shader) {
return false;
}

if (material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}

return material->shader->spatial.uses_ensure_correct_normals;
}

void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) {

Material *material = material_owner.get(p_material);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gles3/rasterizer_storage_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
bool uses_screen_texture;
bool uses_depth_texture;
bool uses_time;
bool uses_tangent;
bool uses_ensure_correct_normals;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
bool uses_world_coordinates;
Expand Down Expand Up @@ -606,6 +608,8 @@ class RasterizerStorageGLES3 : public RasterizerStorage {

virtual bool material_is_animated(RID p_material);
virtual bool material_casts_shadows(RID p_material);
virtual bool material_uses_tangents(RID p_material);
virtual bool material_uses_ensure_correct_normals(RID p_material);

virtual void material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
virtual void material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance);
Expand Down
Loading

0 comments on commit f954471

Please sign in to comment.