diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index abf0376..d432a73 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -345,7 +345,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) { } if(m_pSkyBoxTexture) { - getContext().getShaderManager()->selectShader("sky_box", *this, std::vector(), m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE); + getContext().getShaderManager()->selectShader("sky_box", *this, std::vector(), 0, m_viewport, KRMat4(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_OPAQUE); getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); @@ -461,7 +461,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) { GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); - KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); KRMat4 projectionMatrix = getProjectionMatrix(); @@ -471,7 +471,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) { matModel.scale((*itr).first.size() / 2.0f); matModel.translate((*itr).first.center()); - if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + if(getContext().getShaderManager()->selectShader(*this, pVisShader, m_viewport, matModel, std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); } } @@ -665,8 +665,8 @@ void KRCamera::renderPost() GLDEBUG(glDisable(GL_DEPTH_TEST)); - KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + KRShader *postShader = m_pContext->getShaderManager()->getShader("PostShader", this, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + getContext().getShaderManager()->selectShader(*this, postShader, m_viewport, KRMat4(), std::vector(), 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); m_pContext->getTextureManager()->selectTexture(0, NULL); GLDEBUG(glActiveTexture(GL_TEXTURE0)); @@ -726,7 +726,7 @@ void KRCamera::renderPost() const char *szText = m_debug_text.c_str(); if(*szText) { - KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, std::vector(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + KRShader *fontShader = m_pContext->getShaderManager()->getShader("debug_font", this, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index 4ba5c07..9e4168f 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -117,8 +117,8 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector &light light_direction_view_space = KRMat4::Dot(matModelViewInverseTranspose, light_direction_view_space); light_direction_view_space.normalize(); - KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), this_light, renderPass)) { + KRShader *pShader = getContext().getShaderManager()->getShader("light_directional", pCamera, this_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), this_light, 0, renderPass)) { light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]); m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); diff --git a/KREngine/KREngine/Classes/KRLight.cpp b/KREngine/KREngine/Classes/KRLight.cpp index fc153c7..8b451b9 100644 --- a/KREngine/KREngine/Classes/KRLight.cpp +++ b/KREngine/KREngine/Classes/KRLight.cpp @@ -191,9 +191,9 @@ void KRLight::render(KRCamera *pCamera, std::vector &lights, const KR std::vector this_light; this_light.push_back(this); - KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("dust_particle", pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("dust_particle", pCamera, this_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_light, renderPass)) { + if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, particleModelMatrix, this_light, 0, renderPass)) { (m_color * pCamera->dust_particle_intensity * m_dust_particle_intensity * m_intensity).setUniform(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); @@ -215,10 +215,10 @@ void KRLight::render(KRCamera *pCamera, std::vector &lights, const KR std::vector this_light; this_light.push_back(this); - KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES); + KRShader *pFogShader = m_pContext->getShaderManager()->getShader(shader_name, pCamera, this_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_ADDITIVE_PARTICLES); - if(getContext().getShaderManager()->selectShader(*pCamera, pFogShader, viewport, KRMat4(), this_light, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) { + if(getContext().getShaderManager()->selectShader(*pCamera, pFogShader, viewport, KRMat4(), this_light, 0, KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE)) { int slice_count = (int)(pCamera->volumetric_environment_quality * 495.0) + 5; float slice_near = -pCamera->getPerspectiveNearZ(); @@ -246,8 +246,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &lights, const KR GLDEBUG(glDepthRangef(0.0, 1.0)); // Render light flare on transparency pass - KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), lights, renderPass)) { + KRShader *pShader = getContext().getShaderManager()->getShader("flare", pCamera, lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), lights, 0, renderPass)) { GLDEBUG(glUniform1f( pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], m_flareSize @@ -368,9 +368,9 @@ void KRLight::renderShadowBuffers(KRCamera *pCamera) GLDEBUG(glDisable(GL_BLEND)); // Use shader program - KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::vector(), false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); + KRShader *shadowShader = m_pContext->getShaderManager()->getShader("ShadowShader", pCamera, std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector(), KRNode::RENDER_PASS_SHADOWMAP); + getContext().getShaderManager()->selectShader(*pCamera, shadowShader, m_shadowViewports[iShadow], KRMat4(), std::vector(), 0, KRNode::RENDER_PASS_SHADOWMAP); getScene().render(pCamera, m_shadowViewports[iShadow].getVisibleBounds(), m_shadowViewports[iShadow], KRNode::RENDER_PASS_SHADOWMAP, true); diff --git a/KREngine/KREngine/Classes/KRMaterial.cpp b/KREngine/KREngine/Classes/KRMaterial.cpp index 85b1e20..67102af 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -214,7 +214,7 @@ bool KRMaterial::isTransparent() { } #if TARGET_OS_IPHONE -bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { +bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &lights, const std::vector &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass) { bool bSameMaterial = *prevBoundMaterial == this; bool bLightMap = pLightMap && pCamera->bEnableLightMap; @@ -251,11 +251,11 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC bool bAlphaBlend = (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE) || (m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE); - KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); + KRShader *pShader = getContext().getShaderManager()->getShader("ObjectShader", pCamera, lights, bones.size(), bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_reflectionMapScale != default_scale && bReflectionMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_reflectionMapOffset != default_offset && bReflectionMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, bAlphaBlend, renderPass); bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0; if(!bSameShader) { - if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, lights, renderPass)) { + if(!getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, matModel, lights, 0, renderPass)) { return false; } @@ -263,6 +263,20 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC } GLDEBUG(glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SHININESS], pCamera->bDebugSuperShiny ? 20.0 : m_ns )); + // Bind bones + if(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS] != -1) { + GLfloat bone_mats[256 * 16]; + GLfloat *bone_mat_component = bone_mats; + for(int bone_index=0; bone_index < bones.size(); bone_index++) { + KRBone *bone = bones[bone_index]; + KRMat4 t = bone->getInverseBindPoseMatrix() * bone->getModelMatrix(); + for(int i=0; i < 16; i++) { + *bone_mat_component++ = t[i]; + } + } + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_BONE_TRANSFORMS], bones.size(), GL_FALSE, bone_mats); + } + bool bSameAmbient = false; bool bSameDiffuse = false; bool bSameSpecular = false; diff --git a/KREngine/KREngine/Classes/KRMaterial.h b/KREngine/KREngine/Classes/KRMaterial.h index a3ee627..fa38fba 100644 --- a/KREngine/KREngine/Classes/KRMaterial.h +++ b/KREngine/KREngine/Classes/KRMaterial.h @@ -44,6 +44,7 @@ using std::list; #import "KRResource.h" #import "KRVector2.h" #import "KRScene.h" +#import "KRBone.h" #ifndef KRMATERIAL_H #define KRMATERIAL_H @@ -89,7 +90,7 @@ public: char *getName(); #if TARGET_OS_IPHONE - bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); + bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, std::vector &lights, const std::vector &bones, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass); #endif diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index 761f447..55209dd 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -165,7 +165,7 @@ void KRModel::render(KRCamera *pCamera, std::vector &lights, const KR if(pMaterial != NULL && pMaterial == (*mat_itr)) { if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { - if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, lights, viewport, matModel, pLightMap, renderPass)) { + if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, lights, bones, viewport, matModel, pLightMap, renderPass)) { switch(pMaterial->getAlphaMode()) { case KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE: // Non-transparent materials diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index c9d9859..0a10fe2 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -33,7 +33,10 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont m_pScene = &scene; getScene().notify_sceneGraphCreate(this); m_modelMatrixValid = false; + m_bindPoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; m_modelMatrix = KRMat4(); + m_bindPoseMatrix = KRMat4(); } KRNode::~KRNode() { @@ -78,20 +81,22 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) { e->QueryFloatAttribute("translate_y", &y); e->QueryFloatAttribute("translate_z", &z); m_localTranslation = KRVector3(x,y,z); - m_originalLocalTranslation = m_localTranslation; + m_initialLocalTranslation = m_localTranslation; e->QueryFloatAttribute("scale_x", &x); e->QueryFloatAttribute("scale_y", &y); e->QueryFloatAttribute("scale_z", &z); m_localScale = KRVector3(x,y,z); - m_originalLocalScale = m_localScale; + m_initialLocalScale = m_localScale; e->QueryFloatAttribute("rotate_x", &x); e->QueryFloatAttribute("rotate_y", &y); e->QueryFloatAttribute("rotate_z", &z); m_localRotation = KRVector3(x,y,z) / 180.0 * M_PI; // Convert degrees to radians - m_originalLocalRotation = m_localRotation; + m_initialLocalRotation = m_localRotation; + m_bindPoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; m_modelMatrixValid = false; for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { @@ -106,18 +111,18 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) { void KRNode::setLocalTranslation(const KRVector3 &v, bool set_original) { m_localTranslation = v; - if(set_original) m_originalLocalTranslation = v; + if(set_original) m_initialLocalTranslation = v; invalidateModelMatrix(); } void KRNode::setLocalScale(const KRVector3 &v, bool set_original) { m_localScale = v; - if(set_original) m_originalLocalScale = v; + if(set_original) m_initialLocalScale = v; invalidateModelMatrix(); } void KRNode::setLocalRotation(const KRVector3 &v, bool set_original) { m_localRotation = v; - if(set_original) m_originalLocalRotation = v; + if(set_original) m_initialLocalRotation = v; invalidateModelMatrix(); } @@ -224,17 +229,7 @@ const KRMat4 &KRNode::getModelMatrix() if(!m_modelMatrixValid) { m_modelMatrix = KRMat4(); - -// if(m_parentNode) { -// m_modelMatrix *= m_parentNode->getModelMatrix(); -// } -// m_modelMatrix.translate(m_localTranslation); -// m_modelMatrix.rotate(m_localRotation.x, X_AXIS); -// m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); -// m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); -// m_modelMatrix.scale(m_localScale); - m_modelMatrix.scale(m_localScale); m_modelMatrix.rotate(m_localRotation.x, X_AXIS); m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); @@ -251,6 +246,36 @@ const KRMat4 &KRNode::getModelMatrix() return m_modelMatrix; } +const KRMat4 &KRNode::getBindPoseMatrix() +{ + if(!m_bindPoseMatrixValid) { + m_bindPoseMatrix = KRMat4(); + + m_bindPoseMatrix.scale(m_initialLocalScale); + m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS); + m_bindPoseMatrix.translate(m_initialLocalTranslation); + + KRBone *parentBone = dynamic_cast(m_parentNode); + + if(parentBone) { + m_bindPoseMatrix *= parentBone->getBindPoseMatrix(); + } + + m_bindPoseMatrixValid = true; + } + return m_bindPoseMatrix; +} + +const KRMat4 &KRNode::getInverseBindPoseMatrix() +{ + if(!m_inverseBindPoseMatrixValid ) { + m_inverseBindPoseMatrix = KRMat4::Invert(getBindPoseMatrix()); + m_inverseBindPoseMatrixValid = true; + } + return m_inverseBindPoseMatrix; +} void KRNode::physicsUpdate(float deltaTime) { diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index 3b5449e..44794b7 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -69,6 +69,8 @@ public: virtual KRAABB getBounds(); const KRMat4 &getModelMatrix(); + const KRMat4 &getBindPoseMatrix(); + const KRMat4 &getInverseBindPoseMatrix(); enum node_attribute_type { KRENGINE_NODE_ATTRIBUTE_NONE, @@ -100,14 +102,18 @@ protected: KRVector3 m_localScale; KRVector3 m_localRotation; - KRVector3 m_originalLocalTranslation; - KRVector3 m_originalLocalScale; - KRVector3 m_originalLocalRotation; + KRVector3 m_initialLocalTranslation; + KRVector3 m_initialLocalScale; + KRVector3 m_initialLocalRotation; private: void invalidateModelMatrix(); KRMat4 m_modelMatrix; + KRMat4 m_bindPoseMatrix; + KRMat4 m_inverseBindPoseMatrix; bool m_modelMatrixValid; + bool m_bindPoseMatrixValid; + bool m_inverseBindPoseMatrixValid; std::string m_name; diff --git a/KREngine/KREngine/Classes/KRParticleSystemNewtonian.cpp b/KREngine/KREngine/Classes/KRParticleSystemNewtonian.cpp index 658a758..7e1ec99 100644 --- a/KREngine/KREngine/Classes/KRParticleSystemNewtonian.cpp +++ b/KREngine/KREngine/Classes/KRParticleSystemNewtonian.cpp @@ -71,9 +71,9 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector int particle_count = 10000; - KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("dust_particle", pCamera, lights, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + KRShader *pParticleShader = m_pContext->getShaderManager()->getShader("dust_particle", pCamera, lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), lights, renderPass)) { + if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), lights, 0, renderPass)) { GLDEBUG(glUniform1f( pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], 1.0f diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index fb04955..b15c675 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -71,9 +71,9 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &lights, con bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ()); - KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, this_light, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + KRShader *pShader = getContext().getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, this_light, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, renderPass)) { + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, this_light, 0, renderPass)) { diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index 3fca05c..308600e 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -239,7 +239,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map &visibleBo GLDEBUG(glDepthMask(GL_FALSE)); } - if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, lights, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { + if(getContext().getShaderManager()->selectShader("occlusion_test", *pCamera, lights, 0, viewport, matModel, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 14)); } diff --git a/KREngine/KREngine/Classes/KRShader.cpp b/KREngine/KREngine/Classes/KRShader.cpp index 42ab670..bd07299 100644 --- a/KREngine/KREngine/Classes/KRShader.cpp +++ b/KREngine/KREngine/Classes/KRShader.cpp @@ -197,6 +197,7 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st GLDEBUG(m_uniforms[KRENGINE_UNIFORM_PARTICLE_ORIGIN] = glGetUniformLocation(m_iProgram, "particle_origin")); + GLDEBUG(m_uniforms[KRENGINE_UNIFORM_BONE_TRANSFORMS] = glGetUniformLocation(m_iProgram, "bone_transforms")); } diff --git a/KREngine/KREngine/Classes/KRShader.h b/KREngine/KREngine/Classes/KRShader.h index 18175fc..c885148 100644 --- a/KREngine/KREngine/Classes/KRShader.h +++ b/KREngine/KREngine/Classes/KRShader.h @@ -134,6 +134,8 @@ public: KRENGINE_UNIFORM_PARTICLE_ORIGIN, + KRENGINE_UNIFORM_BONE_TRANSFORMS, + KRENGINE_NUM_UNIFORMS }; GLint m_uniforms[KRENGINE_NUM_UNIFORMS]; diff --git a/KREngine/KREngine/Classes/KRShaderManager.cpp b/KREngine/KREngine/Classes/KRShaderManager.cpp index 4808ad2..c461f76 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.cpp +++ b/KREngine/KREngine/Classes/KRShaderManager.cpp @@ -50,7 +50,7 @@ KRShaderManager::~KRShaderManager() { } -KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { +KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { int iShadowQuality = 0; // FINDME - HACK - Placeholder code, need to iterate through lights and dynamically build shader @@ -78,7 +78,7 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p } char szKey[256]; - sprintf(szKey, "%i_%i_%i_%i_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", light_directional_count, light_point_count, light_spot_count, pCamera->fog_type, pCamera->bEnablePerPixel,bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset,pCamera->volumetric_environment_enable && pCamera->volumetric_environment_downsample != 0, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff); + sprintf(szKey, "%i_%i_%i_%i_%i_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", light_directional_count, light_point_count, light_spot_count, bone_count, pCamera->fog_type, pCamera->bEnablePerPixel,bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset,pCamera->volumetric_environment_enable && pCamera->volumetric_environment_downsample != 0, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff); KRShader *pShader = m_shaders[szKey]; @@ -94,8 +94,9 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p stringstream stream; stream.precision(std::numeric_limits::digits10); stream << "\n#define LIGHT_DIRECTIONAL_COUNT " << light_directional_count; - stream << "#define LIGHT_POINT_COUNT " << light_point_count; - stream << "#define LIGHT_SPOT_COUNT " << light_spot_count; + stream << "\n#define LIGHT_POINT_COUNT " << light_point_count; + stream << "\n#define LIGHT_SPOT_COUNT " << light_spot_count; + stream << "\n#define BONE_COUNT " << bone_count; stream << "\n#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0"); stream << "\n#define HAS_DIFFUSE_MAP_SCALE " << (bDiffuseMapScale ? "1" : "0"); @@ -170,13 +171,13 @@ KRShader *KRShaderManager::getShader(const std::string &shader_name, KRCamera *p return pShader; } -bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) +bool KRShaderManager::selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { - KRShader *pShader = getShader(shader_name, &camera, lights, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass); - return selectShader(camera, pShader, viewport, matModel, lights, renderPass); + KRShader *pShader = getShader(shader_name, &camera, lights, bone_count, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bReflectionMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, bReflectionMapOffset, bAlphaTest, bAlphaBlend, renderPass); + return selectShader(camera, pShader, viewport, matModel, lights, bone_count, renderPass); } -bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, const KRNode::RenderPass &renderPass) +bool KRShaderManager::selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, int bone_count, const KRNode::RenderPass &renderPass) { if(pShader) { bool bSameShader = strcmp(pShader->getKey(), m_szCurrentShaderKey) == 0; diff --git a/KREngine/KREngine/Classes/KRShaderManager.h b/KREngine/KREngine/Classes/KRShaderManager.h index 3cbc826..76a7742 100644 --- a/KREngine/KREngine/Classes/KRShaderManager.h +++ b/KREngine/KREngine/Classes/KRShaderManager.h @@ -59,11 +59,11 @@ public: const std::string &getVertShaderSource(const std::string &name); - KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &lights, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); + KRShader *getShader(const std::string &shader_name, KRCamera *pCamera, const std::vector &lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); - bool selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, const KRNode::RenderPass &renderPass); + bool selectShader(KRCamera &camera, const KRShader *pShader, const KRViewport &viewport, const KRMat4 &matModel, const std::vector &lights, int bone_count, const KRNode::RenderPass &renderPass); - bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &lights, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); + bool selectShader(const std::string &shader_name, KRCamera &camera, const std::vector &lights, int bone_count, const KRViewport &viewport, const KRMat4 &matModel, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); long getShaderHandlesUsed(); diff --git a/KREngine/KREngine/Shaders/ObjectShader.vsh b/KREngine/KREngine/Shaders/ObjectShader.vsh index 4cd50a9..e6f0fa8 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.vsh +++ b/KREngine/KREngine/Shaders/ObjectShader.vsh @@ -31,7 +31,19 @@ attribute highp vec3 vertex_position, vertex_normal, vertex_tangent; attribute mediump vec2 vertex_uv; -uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices +uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices + +#if BONE_COUNT > 0 + attribute highp vec4 bone_weights; + attribute lowp vec4 bone_indexes; + uniform highp mat4 bone_transforms[BONE_COUNT]; +#else + #define vertex_position_skinned vertex_position + #define vertex_normal_skinned vertex_normal + #define vertex_tangent_skinned vertex_tangent +#endif + + #if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1 #if HAS_DIFFUSE_MAP == 1 || HAS_NORMAL_MAP == 1 || HAS_SPEC_MAP == 1 || HAS_REFLECTION_MAP == 1 @@ -152,8 +164,29 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t void main() { +#if BONE_COUNT > 0 + highp vec3 vertex_position_skinned = + ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.w); + + highp vec3 vertex_normal_skinned = normalize( + ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.w)); + + highp vec3 vertex_tangent_skinned = normalize( + ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.w)); +#endif + + // Transform position - gl_Position = mvp_matrix * vec4(vertex_position,1.0); + gl_Position = mvp_matrix * vec4(vertex_position_skinned,1.0); #if HAS_DIFFUSE_MAP == 1 || (HAS_NORMAL_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_REFLECTION_MAP == 1 && ENABLE_PER_PIXEL == 1) // Pass UV co-ordinates @@ -195,23 +228,23 @@ void main() #if GBUFFER_PASS == 1 #if HAS_NORMAL_MAP == 1 - mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent); - tangent_to_view_matrix[0] = vec3(model_view_inverse_transpose_matrix * vec4(vertex_tangent, 1.0)); + mediump vec3 a_bitangent = cross(vertex_normal_skinned, vertex_tangent_skinned); + tangent_to_view_matrix[0] = vec3(model_view_inverse_transpose_matrix * vec4(vertex_tangent_skinned, 1.0)); tangent_to_view_matrix[1] = vec3(model_view_inverse_transpose_matrix * vec4(a_bitangent, 1.0)); - tangent_to_view_matrix[2] = vec3(model_view_inverse_transpose_matrix * vec4(vertex_normal, 1.0)); + tangent_to_view_matrix[2] = vec3(model_view_inverse_transpose_matrix * vec4(vertex_normal_skinned, 1.0)); #else - normal = vertex_normal; + normal = vertex_normal_skinned; #endif #else #if HAS_REFLECTION_CUBE_MAP == 1 #if HAS_NORMAL_MAP == 1 - eyeVec = normalize(camera_position_model_space - vertex_position); + eyeVec = normalize(camera_position_model_space - vertex_position_skinned); #else // Calculate reflection vector as I - 2.0 * dot(N, I) * N - mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position); + mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position_skinned); mediump vec3 incidenceVec = -eyeVec; - reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(vertex_normal, incidenceVec) * vertex_normal); + reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(vertex_normal_skinned, incidenceVec) * vertex_normal_skinned); #endif #endif @@ -250,45 +283,45 @@ void main() #if SHADOW_QUALITY >= 1 - shadowMapCoord1 = shadow_mvp1 * vec4(vertex_position,1.0); + shadowMapCoord1 = shadow_mvp1 * vec4(vertex_position_skinned,1.0); #endif #if SHADOW_QUALITY >= 2 - shadowMapCoord2 = shadow_mvp2 * vec4(vertex_position,1.0); + shadowMapCoord2 = shadow_mvp2 * vec4(vertex_position_skinned,1.0); #endif #if SHADOW_QUALITY >= 3 - shadowMapCoord3 = shadow_mvp3 * vec4(vertex_position,1.0); + shadowMapCoord3 = shadow_mvp3 * vec4(vertex_position_skinned,1.0); #endif // ----------- Directional Light (Sun) ----------- #if HAS_NORMAL_MAP == 1 // ----- Calculate per-pixel lighting in tangent space, for normal mapping ------ - mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent); + mediump vec3 a_bitangent = cross(vertex_normal_skinned, vertex_tangent_skinned); #if HAS_REFLECTION_CUBE_MAP == 0 // The cube map reflections also require an eyeVec as a varying attribute when normal mapping, so only re-calculate here when needed - mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position); + mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position_skinned); #else - tangent_to_world_matrix[0] = vec3(model_inverse_transpose_matrix * vec4(vertex_tangent, 1.0)); + tangent_to_world_matrix[0] = vec3(model_inverse_transpose_matrix * vec4(vertex_tangent_skinned, 1.0)); tangent_to_world_matrix[1] = vec3(model_inverse_transpose_matrix * vec4(a_bitangent, 1.0)); - tangent_to_world_matrix[2] = vec3(model_inverse_transpose_matrix * vec4(vertex_normal, 1.0)); + tangent_to_world_matrix[2] = vec3(model_inverse_transpose_matrix * vec4(vertex_normal_skinned, 1.0)); #endif - lightVec = normalize(vec3(dot(light_direction_model_space, vertex_tangent), dot(light_direction_model_space, a_bitangent), dot(light_direction_model_space, vertex_normal))); - halfVec = normalize(vec3(dot(eyeVec, vertex_tangent), dot(eyeVec, a_bitangent), dot(eyeVec, vertex_normal))); + lightVec = normalize(vec3(dot(light_direction_model_space, vertex_tangent_skinned), dot(light_direction_model_space, a_bitangent), dot(light_direction_model_space, vertex_normal_skinned))); + halfVec = normalize(vec3(dot(eyeVec, vertex_tangent_skinned), dot(eyeVec, a_bitangent), dot(eyeVec, vertex_normal_skinned))); halfVec = normalize(halfVec + lightVec); // Normalizing anyways, no need to divide by 2 #else // ------ Calculate per-pixel lighting without normal mapping ------ - normal = vertex_normal; + normal = vertex_normal_skinned; lightVec = light_direction_model_space; - halfVec = normalize((normalize(camera_position_model_space - vertex_position) + lightVec)); // Normalizing anyways, no need to divide by 2 + halfVec = normalize((normalize(camera_position_model_space - vertex_position_skinned) + lightVec)); // Normalizing anyways, no need to divide by 2 #endif #else // ------ Calculate per-vertex lighting ------ - mediump vec3 halfVec = normalize((normalize(camera_position_model_space - vertex_position) + light_direction_model_space)); // Normalizing anyways, no need to divide by 2 - lamberFactor = max(0.0,dot(light_direction_model_space, vertex_normal)); - specularFactor = max(0.0,pow(dot(halfVec,vertex_normal), material_shininess)); + mediump vec3 halfVec = normalize((normalize(camera_position_model_space - vertex_position_skinned) + light_direction_model_space)); // Normalizing anyways, no need to divide by 2 + lamberFactor = max(0.0,dot(light_direction_model_space, vertex_normal_skinned)); + specularFactor = max(0.0,pow(dot(halfVec,vertex_normal_skinned), material_shininess)); #endif #endif }