Skip to content

Commit

Permalink
Fix rigged animations
Browse files Browse the repository at this point in the history
Texture based model has degraded performance, but
overall it is an improvement.
  • Loading branch information
enginmanap committed Dec 30, 2024
1 parent f54cb18 commit 44e8447
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 97 deletions.
26 changes: 14 additions & 12 deletions Engine/Shaders/ModelAnimated/vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,27 @@ struct LightSource {
};

uniform sampler2D allModelTransformsTexture;
uniform sampler2D allBoneTransformsTexture;

layout (std140) uniform ModelIndexBlock {
uvec4 models[NR_MAX_MODELS];
} instance;

struct rigBones {
mat4 transform[NR_BONE];
};

layout (std140) uniform AllAnimationsBlock {
rigBones rigs[8];
} animation;

layout (std140) uniform LightSourceBlock {
LightSource lights[NR_POINT_LIGHTS];
} LightSources;

uniform bool isAnimated;

mat4 getMatrixFromRigTexture(uint rigIndex, uint boneIndex) {
mat4 matrix;
matrix[0] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) , int(rigIndex)), 0);
matrix[1] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 1, int(rigIndex)), 0);
matrix[2] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 2, int(rigIndex)), 0);
matrix[3] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 3, int(rigIndex)), 0);
return matrix;
}

void main(void) {
to_fs.textureCoord = textureCoordinate;
mat4 modelTransform;
Expand All @@ -78,10 +80,10 @@ void main(void) {

if(isAnimated) {
uint skeletonId = instance.models[gl_InstanceID].z;
mat4 BoneTransform = animation.rigs[skeletonId].transform[boneIDs[0]] * boneWeights[0];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[1]] * boneWeights[1];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[2]] * boneWeights[2];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[3]] * boneWeights[3];
mat4 BoneTransform = getMatrixFromRigTexture(skeletonId, boneIDs[0]) * boneWeights[0];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[1]) * boneWeights[1];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[2]) * boneWeights[2];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[3]) * boneWeights[3];

to_fs.normal = normalize(transposeInverseModelTransform * vec3(BoneTransform * vec4(normal, 0.0)));
to_fs.fragPos = vec3(modelTransform * (BoneTransform * position));
Expand Down
8 changes: 0 additions & 8 deletions Engine/Shaders/ModelTransparent/vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ layout (std140) uniform ModelIndexBlock {
uvec4 models[NR_MAX_MODELS];
} instance;

struct BoneTransform {
mat4 transforms[NR_BONE];
};

layout (std140) uniform AllAnimationsBlock {
BoneTransform rigs[8];
} animation;

layout (std140) uniform LightSourceBlock
{
LightSource lights[NR_POINT_LIGHTS];
Expand Down
26 changes: 14 additions & 12 deletions Engine/Shaders/ShadowMapDirectional/vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,14 @@ struct LightSource {
vec3 ambient;
};

struct rigBones {
mat4 transform[NR_BONE];
};

layout (std140) uniform AllAnimationsBlock {
rigBones rigs[8];
} animation;

layout (std140) uniform LightSourceBlock
{
LightSource lights[NR_POINT_LIGHTS];
} LightSources;


uniform sampler2D allModelTransformsTexture;
uniform sampler2D allBoneTransformsTexture;

layout (std140) uniform ModelIndexBlock {
uvec4 models[NR_MAX_MODELS];
Expand All @@ -44,15 +37,24 @@ uniform int renderLightLayer;

uniform int isAnimated;

mat4 getMatrixFromRigTexture(uint rigIndex, uint boneIndex) {
mat4 matrix;
matrix[0] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) , int(rigIndex)), 0);
matrix[1] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 1, int(rigIndex)), 0);
matrix[2] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 2, int(rigIndex)), 0);
matrix[3] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 3, int(rigIndex)), 0);
return matrix;
}

void main() {

mat4 BoneTransform = mat4(1.0);
if(isAnimated==1) {
uint skeletonId = instance.models[gl_InstanceID].z;
BoneTransform = animation.rigs[skeletonId].transform[boneIDs[0]] * boneWeights[0];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[1]] * boneWeights[1];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[2]] * boneWeights[2];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[3]] * boneWeights[3];
BoneTransform = getMatrixFromRigTexture(skeletonId, boneIDs[0]) * boneWeights[0];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[1]) * boneWeights[1];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[2]) * boneWeights[2];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[3]) * boneWeights[3];
}

mat4 modelTransform;
Expand Down
27 changes: 15 additions & 12 deletions Engine/Shaders/ShadowMapPoint/vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,35 @@ layout (std140) uniform LightSourceBlock


uniform sampler2D allModelTransformsTexture;
uniform sampler2D allBoneTransformsTexture;

layout (std140) uniform ModelIndexBlock {
uvec4 models[NR_MAX_MODELS];
} instance;

struct rigBones {
mat4 transform[NR_BONE];
};

layout (std140) uniform AllAnimationsBlock {
rigBones rigs[8];
} animation;

uniform int renderLightIndex;
uniform int isAnimated;

mat4 getMatrixFromRigTexture(uint rigIndex, uint boneIndex) {
mat4 matrix;
matrix[0] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) , int(rigIndex)), 0);
matrix[1] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 1, int(rigIndex)), 0);
matrix[2] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 2, int(rigIndex)), 0);
matrix[3] = texelFetch(allBoneTransformsTexture, ivec2(int(boneIndex*4u) + 3, int(rigIndex)), 0);
return matrix;
}

void main() {

mat4 BoneTransform = mat4(1.0);
if(isAnimated==1) {
uint skeletonId = instance.models[gl_InstanceID].z;
BoneTransform = animation.rigs[skeletonId].transform[boneIDs[0]] * boneWeights[0];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[1]] * boneWeights[1];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[2]] * boneWeights[2];
BoneTransform += animation.rigs[skeletonId].transform[boneIDs[3]] * boneWeights[3];
mat4 BoneTransform = getMatrixFromRigTexture(skeletonId, boneIDs[0]) * boneWeights[0];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[1]) * boneWeights[1];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[2]) * boneWeights[2];
BoneTransform += getMatrixFromRigTexture(skeletonId, boneIDs[3]) * boneWeights[3];
}

for(int i = 0; i < NR_POINT_LIGHTS; i++){
if(i == renderLightIndex){
mat4 modelTransform;
Expand Down
54 changes: 23 additions & 31 deletions GraphicBackends/OpenGLGraphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,18 @@ Uniform::VariableTypes OpenGLGraphics::getSamplerVariableType(const GLint *query
return variableType;
}


void OpenGLGraphics::attachModelUBO(const uint32_t program) {
void OpenGLGraphics::attachModelTexture(const uint32_t program) {
GLint allModelsAttachPoint = glGetUniformLocation(program, "allModelTransformsTexture");
this->setUniform(program, allModelsAttachPoint, maxTextureImageUnits-3);
state->attachTexture(allModelTransformsTexture, maxTextureImageUnits-3);
checkErrors("attachModelUBO");
checkErrors("attachModelTexture");
}

void OpenGLGraphics::attachRigTexture(const uint32_t program) {
GLint allBonesAttachPoint = glGetUniformLocation(program, "allBoneTransformsTexture");
this->setUniform(program, allBonesAttachPoint, maxTextureImageUnits-4);
state->attachTexture(allBoneTransformsTexture, maxTextureImageUnits-4);
checkErrors("attachRigTexture");
}

void OpenGLGraphics::attachModelIndicesUBO(const uint32_t programID) {
Expand All @@ -278,7 +284,6 @@ void OpenGLGraphics::attachModelIndicesUBO(const uint32_t programID) {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
checkErrors("attachModelIndicesUBO");
attachBoneTransformsUBO(programID);
}

void OpenGLGraphics::attachMaterialUBO(const uint32_t program){
Expand All @@ -295,21 +300,6 @@ void OpenGLGraphics::attachMaterialUBO(const uint32_t program){
checkErrors("attachMaterialUBO");
}

void OpenGLGraphics::attachBoneTransformsUBO(const uint32_t program){
GLuint allBoneTransformsAttachPoint = 10;

int uniformIndex = glGetUniformBlockIndex(program, "AllAnimationsBlock");
if (uniformIndex >= 0) {
glBindBuffer(GL_UNIFORM_BUFFER, allBoneTransformsUBOLocation);
glUniformBlockBinding(program, uniformIndex, allBoneTransformsAttachPoint);
glBindBufferBase(GL_UNIFORM_BUFFER, allBoneTransformsAttachPoint, allBoneTransformsUBOLocation);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

checkErrors("attachBoneTransformsUBO");
}


void OpenGLGraphics::attachGeneralUBOs(const GLuint program){//Attach the light block to our UBO

GLuint lightAttachPoint = 0, playerAttachPoint = 1;
Expand Down Expand Up @@ -489,11 +479,13 @@ bool OpenGLGraphics::createGraphicsBackend() {
glBufferData(GL_UNIFORM_BUFFER, materialUniformSize * NR_MAX_MATERIALS, nullptr, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

//create bone transform array uniform buffer object
glGenBuffers(1, &allBoneTransformsUBOLocation);
glBindBuffer(GL_UNIFORM_BUFFER, allBoneTransformsUBOLocation);
glBufferData(GL_UNIFORM_BUFFER, NR_BONE * sizeof(glm::mat4) * 8, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glGenTextures(1, &allBoneTransformsTexture);
state->activateTextureUnit(maxTextureImageUnits-4);
glBindTexture(GL_TEXTURE_2D, allBoneTransformsTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4 * NR_BONE, NR_MAX_MODELS, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
state->activateTextureUnit(0);

glGenTextures(1, &allModelTransformsTexture);
state->activateTextureUnit(maxTextureImageUnits-3);
Expand Down Expand Up @@ -981,10 +973,7 @@ OpenGLGraphics::~OpenGLGraphics() {
deleteBuffer(1, lightUBOLocation);
deleteBuffer(1, playerUBOLocation);
deleteBuffer(1, allMaterialsUBOLocation);
deleteBuffer(1, allBoneTransformsUBOLocation);
glDeleteFramebuffers(1, &combineFrameBuffer);

//state->setProgram(0);
}

void OpenGLGraphics::reshape() {
Expand Down Expand Up @@ -1554,13 +1543,16 @@ void OpenGLGraphics::setMaterial(const Material& material) {
checkErrors("setMaterial");
}

void OpenGLGraphics::setBoneTransforms(const std::vector<glm::mat4>& boneTransforms, uint32_t index) {
void OpenGLGraphics::setBoneTransforms(uint32_t index, const std::vector<glm::mat4>& boneTransforms) {
if (boneTransforms.size() > NR_BONE) {
std::cerr << "Too many bones, can't upload more than " << NR_BONE << "ignoring." << std::endl;
}
glBindBuffer(GL_UNIFORM_BUFFER, allBoneTransformsUBOLocation);
glBufferSubData(GL_UNIFORM_BUFFER, NR_BONE * sizeof(glm::mat4) * index, boneTransforms.size() * sizeof(glm::mat4), boneTransforms.data());
glBindBuffer(GL_UNIFORM_BUFFER, 0);
if (boneTransforms.size() < NR_BONE) {
std::cerr << "too little bones, possible garbage upload " << std::endl;
}
state->activateTextureUnit(maxTextureImageUnits-4);
state->attachTexture(allBoneTransformsTexture, maxTextureImageUnits-4);
glTexSubImage2D(GL_TEXTURE_2D,0,0, index, 4*NR_BONE, 1, GL_RGBA, GL_FLOAT, boneTransforms.data());
checkErrors("setBoneTransform");
}

Expand Down
14 changes: 7 additions & 7 deletions GraphicBackends/OpenGLGraphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class OpenGLGraphics : public GraphicsInterface {
GLuint playerUBOLocation;
GLuint allMaterialsUBOLocation;
GLuint allModelIndexesUBOLocation;
GLuint allBoneTransformsUBOLocation;
GLuint allBoneTransformsTexture;

GLuint combineFrameBuffer;

Expand Down Expand Up @@ -323,15 +323,15 @@ class OpenGLGraphics : public GraphicsInterface {

explicit OpenGLGraphics(OptionsUtil::Options *options);

GraphicsInterface::ContextInformation getContextInformation();
bool createGraphicsBackend();
GraphicsInterface::ContextInformation getContextInformation() override;
bool createGraphicsBackend() override;

~OpenGLGraphics();
~OpenGLGraphics() override;

void attachModelUBO(const uint32_t program) override;
void attachModelTexture(const uint32_t program) override;
void attachRigTexture(const uint32_t program) override;

void attachMaterialUBO(const uint32_t program) override;
void attachBoneTransformsUBO(const uint32_t program) override;

void initializeProgramAsset(const uint32_t programId,
std::unordered_map<std::string, std::shared_ptr<Uniform>> &uniformMap,
Expand Down Expand Up @@ -460,7 +460,7 @@ class OpenGLGraphics : public GraphicsInterface {

void setMaterial(const Material& material) override;

void setBoneTransforms(const std::vector<glm::mat4>& boneTransforms, uint32_t index) override;
void setBoneTransforms(uint32_t index, const std::vector<glm::mat4>& boneTransforms) override;

void setModel(const uint32_t modelID, const glm::mat4 &worldTransform) override;

Expand Down
2 changes: 1 addition & 1 deletion samples/SSAOKernelRenderMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ bool SSAOKernelRenderMethod::initRender(std::shared_ptr<GraphicsProgram> program
std::cerr << "uniform variable \"ssaoSampleCount\" couldn't be set" << std::endl;
}
generateSSAONoiseTexture();
if(!program->setUniform("ssaoNoiseSampler", graphicsInterface->getMaxTextureImageUnits()-4)) {
if(!program->setUniform("ssaoNoiseSampler", graphicsInterface->getMaxTextureImageUnits()-5)) {
std::cerr << "uniform variable \"ssaoNoiseSampler\" couldn't be set" << std::endl;
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion samples/SSAOKernelRenderMethod.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class SSAOKernelRenderMethod : public RenderMethodInterface{
bool initRender(std::shared_ptr<GraphicsProgram> program, std::vector<LimonTypes::GenericParameter> parameters [[gnu::unused]]) override;

virtual void renderFrame(std::shared_ptr<GraphicsProgram> program[[gnu::unused]]) {
graphicsInterface->attachTexture(ssaoNoiseTexture, graphicsInterface->getMaxTextureImageUnits()-4);
graphicsInterface->attachTexture(ssaoNoiseTexture, graphicsInterface->getMaxTextureImageUnits()-5);

graphicsInterface->render(program->getID(), vao, ebo, 3 * 2);//2 triangles
};
Expand Down
6 changes: 3 additions & 3 deletions src/API/Graphics/GraphicsInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ class GraphicsInterface {
virtual bool createGraphicsBackend() = 0;
virtual ~GraphicsInterface() {};

virtual void attachModelUBO(const uint32_t program) = 0;
virtual void attachModelTexture(const uint32_t program) = 0;
virtual void attachRigTexture(const uint32_t program) = 0;
virtual void attachMaterialUBO(const uint32_t program) = 0;
virtual void attachBoneTransformsUBO(const uint32_t program) = 0;
virtual void initializeProgramAsset(const uint32_t programId,
std::unordered_map<std::string, std::shared_ptr<Uniform>> &uniformMap, std::unordered_map<std::string, uint32_t> &attributesMap,
std::unordered_map<std::string, std::pair<Uniform::VariableTypes, FrameBufferAttachPoints>> &outputMap) = 0;
Expand Down Expand Up @@ -168,7 +168,7 @@ class GraphicsInterface {
virtual int getMaxTextureImageUnits() const = 0;

virtual void setMaterial(const Material& material) = 0;
virtual void setBoneTransforms(const std::vector<glm::mat4>& boneTransforms, uint32_t index) = 0;
virtual void setBoneTransforms(uint32_t index, const std::vector<glm::mat4>& boneTransforms) = 0;
virtual void setModel(const uint32_t modelID, const glm::mat4 &worldTransform) = 0;
virtual void setModelIndexesUBO(const std::vector<glm::uvec4> & modelIndicesList) = 0;
virtual void attachModelIndicesUBO(const uint32_t programID) = 0;
Expand Down
7 changes: 4 additions & 3 deletions src/API/Graphics/GraphicsProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ GraphicsProgram::GraphicsProgram(AssetManager* assetManager, const std::string&
if(materialRequired) {
setSamplersAndUBOs();
}
graphicsWrapper->attachModelUBO(getID());
graphicsWrapper->attachModelTexture(getID());
graphicsWrapper->attachRigTexture(getID());
graphicsWrapper->attachModelIndicesUBO(getID());
}

Expand All @@ -29,7 +30,8 @@ GraphicsProgram::GraphicsProgram(AssetManager* assetManager, const std::string&
if(materialRequired) {
setSamplersAndUBOs();
}
graphicsWrapper->attachModelUBO(getID());
graphicsWrapper->attachModelTexture(getID());
graphicsWrapper->attachRigTexture(getID());
graphicsWrapper->attachModelIndicesUBO(getID());
}

Expand All @@ -47,7 +49,6 @@ GraphicsProgram::~GraphicsProgram() {
//TODO remove with material editor
void GraphicsProgram::setSamplersAndUBOs() {
graphicsWrapper->attachMaterialUBO(getID());
graphicsWrapper->attachBoneTransformsUBO(getID());

//TODO these will be configurable with material editor
int diffuseMapAttachPoint = 1;
Expand Down
Loading

0 comments on commit 44e8447

Please sign in to comment.