Sign in to follow this  

Flickering in animation system! DirectX Help!

This topic is 397 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys! 

 

So i keep getting this flickering effect whit my animated models! but the flickering is random and i doubt it has anything to do whit the actual animation. So through some research i came to the conclusion that it might be because of the constant buffer data that i am sending over to the GPU where the animations are actually happening. Since i am using D3D11_MAP_WRITE_DISCARD when calling the map/unmap functions i think it might not filling in all of the data. I do know that the flickering does stop when i do not update the constant buffer. which proves that the bug most likely is in the updating of the constant buffer. Only problem is i do not know what data i am not filling in or how i might be updating the buffer wrong.

 

Here is the code where i feel in the structure( BufferAnimStruct ) that is going to be used for the constant buffer

	Animation* Current_Animation = _Model->GetAnimation(_Model->GetCurrentAnimation());
	Mesh* TempMesh = _Model->GetMesh();

	vector<FLOAT4X4> CurrentPoses = ProcessChannels(Current_Animation, _DT);
	BufferAnimStruct ConstStruct = _Model->GetAnimInfo();
	for (unsigned int i = 0; i < TempMesh->The_Joints.size(); i++)
	{
		FLOAT4X4 Temp;
		FLOAT4X4 Bind_Pose = Current_Animation->The_Joints[i].bind_pose_transform;
		Temp = Math::GetInstance()->FLOAT4X4Inverse(Bind_Pose);
		ConstStruct.InverseBindPose[i] = Math::GetInstance()->FLOAT4X4ToXMFLOAT4X4(Temp);
		Temp = CurrentPoses[i];
		ConstStruct.Pose[i] = Math::GetInstance()->FLOAT4X4ToXMFLOAT4X4(Temp);
	}
	_Model->SetAnimInfo(ConstStruct);

and here is the code when i update the buffer

	D3D11_MAPPED_SUBRESOURCE m_SR1 = {};
	Renderer::GetInstance()->GetContext()->Map(m_bAnimConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &m_SR1);
	BufferAnimStruct* BufferAnim = (BufferAnimStruct*)m_SR1.pData;
	memcpy(m_SR1.pData, &m_bAnimInfo, sizeof(BufferAnimStruct));
	Renderer::GetInstance()->GetContext()->Unmap(m_bAnimConstBuffer, 0);

and last but not least here is the code in the vertex shader where the vertexs are moved according to the poses sent through the constant buffer.

cbuffer AnimationInfo : register(b0)
{
	float4x4 InverseBind[30];
	float4x4 Pose[30];
}

OUTPUT_VERTEX main(INPUT_VERTEX fromVertexBuffer)
{
	OUTPUT_VERTEX sendToRasterizer = (OUTPUT_VERTEX)0;

	float4 localH = float4(fromVertexBuffer.coordinate, 1);

	float4 vSum = float4(0, 0, 0, 0);
	int Num = fromVertexBuffer.Number_Influences.x;

	if (Num > 0)
	{
		for (int i = 0; i < Num; i++)
		{
			int JointIndex = fromVertexBuffer.JointIndex[i];
			float4 offset = mul(localH, InverseBind[JointIndex]);
			float4 Result = mul(offset, Pose[JointIndex]);

			Result *= fromVertexBuffer.Weight.x;
			vSum += Result;
		}
		localH = vSum;
	}

	localH = mul(localH, worldMatrix);
	localH = mul(localH, viewMatrix);
	localH = mul(localH, projectionMatrix);

	sendToRasterizer.projectedCoordinate = localH;

	return sendToRasterizer;
}

Thanks for the help.

Share this post


Link to post
Share on other sites

Hi ,

So a few things :

 

1.Why is your math class singleton ? Do you hold any data to need an instnace.

 

2. Limit the weight influences to 4 . Every 3d package can export it like that and its more than enough.The point is the remove the ifs and loops.

 

Maybe at some point of time the calculation of the matrixes goes wrong and you don't see the model.I don't think it's from the constant buffer because I do it the same way. Just make sure the buffer's usage is Dynamic.

Share this post


Link to post
Share on other sites

Hey, dgi

 

Your right the Math class should not be a singleton ive been meaning to change that but this bug has been distracting me. Regardless i just changed the Math class is no longer a singleton thanks for the reminder :D.

 

As for the weights i actually have the influences to be as low as 2. Also the If in the vertex Shader is to ensure other process don't use the Animation code and for the for loop i'm not sure how i could lock it to only 2 or 4 influences since there could be 1 or 3 influences for the vertex.  

 

I FOUND OUT THE PROBLEM! 

 

You led me to the right direction! I was focusing to much of my attention on the buffer updating when in reality it was actually how i was calculating the Key frames between which to interpolate and the ratio for the interpolation.

 

the problem was that the ratio would sometimes go above 1 no longer been a ratio and therefore skewing the matrix's in the interpolation.

 

Thanks for the help! been trying to fix this bug for a few days now :D  Cheers!




Edited by Continuous_Dreamer

Share this post


Link to post
Share on other sites

Happy to help :) if you have two influences on some vertex you can just set the other twi to 0.So you can just unroll the loop and be something like this :

 

v += matrix[v.ind[x]] * v,infl[x]

v + matrix[v.ind[y]] * v.infl[y]

..

 

its just tha fastest way and you can shave off some frames if you have a lot of animations going on .

 

dgi

Share this post


Link to post
Share on other sites

This topic is 397 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this