From 94f6d09bf52590bfba7b31f3e4f0bace7e2d0f4d Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 9 Dec 2016 22:37:17 +0800 Subject: [PATCH] Allow indirect and azdo shadow rendering for skinned mesh --- data/shaders/instanced_skinning_shadow.vert | 72 +++++++++++++++++++++ src/graphics/command_buffer.cpp | 2 + src/graphics/draw_calls.cpp | 2 + src/graphics/materials.hpp | 32 ++++++++- 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 data/shaders/instanced_skinning_shadow.vert diff --git a/data/shaders/instanced_skinning_shadow.vert b/data/shaders/instanced_skinning_shadow.vert new file mode 100644 index 000000000..359980dc1 --- /dev/null +++ b/data/shaders/instanced_skinning_shadow.vert @@ -0,0 +1,72 @@ +uniform int layer; + +layout(location = 0) in vec3 Position; +layout(location = 3) in vec4 Data1; +layout(location = 5) in ivec4 Joint; +layout(location = 6) in vec4 Weight; +layout(location = 7) in vec3 Origin; +layout(location = 8) in vec3 Orientation; +layout(location = 9) in vec3 Scale; +#ifdef Use_Bindless_Texture +layout(location = 11) in uvec2 Handle; +#endif +layout(location = 15) in int skinning_offset; + +#ifdef VSLayer +out vec2 uv; +#ifdef Use_Bindless_Texture +flat out uvec2 handle; +#endif +#else +out vec2 tc; +out int layerId; +#ifdef Use_Bindless_Texture +flat out uvec2 hdle; +#endif +#endif + +#stk_include "utils/getworldmatrix.vert" + +void main(void) +{ + mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); + vec4 idle_position = vec4(Position, 1.); + vec4 skinned_position = vec4(0.); + vec4 single_bone_influenced_position; + + // First bone: + single_bone_influenced_position = joint_matrices[clamp(Joint[0] + skinning_offset, 0, MAX_BONES)] * idle_position; + single_bone_influenced_position /= single_bone_influenced_position.w; + skinned_position += Weight[0] * single_bone_influenced_position; + + // Second bone: + single_bone_influenced_position = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_position; + single_bone_influenced_position /= single_bone_influenced_position.w; + skinned_position += Weight[1] * single_bone_influenced_position; + + // Third bone: + single_bone_influenced_position = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_position; + single_bone_influenced_position /= single_bone_influenced_position.w; + skinned_position += Weight[2] * single_bone_influenced_position; + + // Fourth bone: + single_bone_influenced_position = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_position; + single_bone_influenced_position /= single_bone_influenced_position.w; + skinned_position += Weight[3] * single_bone_influenced_position; + +#ifdef VSLayer + gl_Layer = layer; + gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * skinned_position; + uv = Data1.xy; +#ifdef Use_Bindless_Texture + handle = Handle; +#endif +#else + layerId = layer; + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * skinned_position; + tc = Data1.xy; +#ifdef Use_Bindless_Texture + hdle = Handle; +#endif +#endif +} diff --git a/src/graphics/command_buffer.cpp b/src/graphics/command_buffer.cpp index b12445016..30745ac33 100644 --- a/src/graphics/command_buffer.cpp +++ b/src/graphics/command_buffer.cpp @@ -202,6 +202,8 @@ void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map) { shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + Material::SHADERTYPE_SOLID); + shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + + Material::SHADERTYPE_SOLID_SKINNED_MESH); shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT + Material::SHADERTYPE_ALPHA_TEST); shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT diff --git a/src/graphics/draw_calls.cpp b/src/graphics/draw_calls.cpp index 5d9a2a17b..af86018cf 100644 --- a/src/graphics/draw_calls.cpp +++ b/src/graphics/draw_calls.cpp @@ -808,6 +808,7 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const { m_shadow_cmd_buffer->bind(); m_shadow_cmd_buffer->drawIndirect(cascade); + m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); m_shadow_cmd_buffer->drawIndirect(cascade); @@ -826,6 +827,7 @@ void DrawCalls::multidrawShadows(unsigned cascade) const { m_shadow_cmd_buffer->bind(); m_shadow_cmd_buffer->multidrawShadow(cascade); + m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); m_shadow_cmd_buffer->multidrawShadow(cascade); diff --git a/src/graphics/materials.hpp b/src/graphics/materials.hpp index 5880f698f..99f7ff739 100644 --- a/src/graphics/materials.hpp +++ b/src/graphics/materials.hpp @@ -143,7 +143,6 @@ public: InstancedShadowShader() { #if !defined(USE_GLES2) - // Geometry shader needed // Geometry shader needed if (CVS->getGLSLVersion() < 150) return; @@ -603,7 +602,6 @@ class InstancedDetailedObjectPass2Shader : public TextureShadersupportsHardwareSkinning()) return; loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_object_pass.vert", GL_FRAGMENT_SHADER, "instanced_detailed_object_pass2.frag"); @@ -638,6 +636,7 @@ class InstancedSkinnedMeshPass2Shader : public TextureShadersupportsHardwareSkinning()) return; loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_object_pass2.frag"); assignUniforms(); @@ -650,12 +649,39 @@ public: } // InstancedSkinnedMeshPass2Shader }; // InstancedSkinnedMeshPass2Shader +// ============================================================================ +class InstancedSkinningShadowShader : public TextureShader +{ +public: + InstancedSkinningShadowShader() + { +#if !defined(USE_GLES2) + // Geometry shader needed + if (CVS->getGLSLVersion() < 150 || !CVS->supportsHardwareSkinning()) + return; + if (CVS->isAMDVertexShaderLayerUsable()) + { + loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + GL_FRAGMENT_SHADER, "shadow.frag"); + } + else + { + loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + GL_GEOMETRY_SHADER, "instanced_shadow.geom", + GL_FRAGMENT_SHADER, "shadow.frag"); + } + assignUniforms("layer"); +#endif + } // InstancedSkinningShadowShader + +}; // InstancedSkinningShadowShader + // ============================================================================ struct SkinnedSolid { typedef InstancedSkinnedMeshPass1Shader InstancedFirstPassShader; typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader; - //typedef InstancedShadowShader InstancedShadowPassShader; + typedef InstancedSkinningShadowShader InstancedShadowPassShader; //typedef CInstancedRSMShader InstancedRSMShader; typedef Shaders::SkinnedMeshPass1Shader FirstPassShader; typedef Shaders::SkinnedMeshPass2Shader SecondPassShader;