• Home
  • About
    • 게임 개발자 유정룡 photo

      게임 개발자 유정룡

      포트폴리오

    • Learn More
    • Email
    • Github
    • Bitbucket
  • Projects
    • All Projects
    • All Tags

Direct3D11 공부 32일차(MultiBone)

12 Jul 2021

Reading time ~1 minute

MultiBone

현재 만들었던 모델에서 원하는 본의 위치를 알기 위해 본을 ComputeShader로 넘겨서 만들어준다.

ModelAnimator

ModelAnimator::ModelAnimator(Shader * shader)
	: shader(shader)
{
	model = new Model();

	tweenBuffer = new ConstantBuffer(&tweenDesc, sizeof(TweenDesc) * MAX_MODEL_INSTANCE);
	sTweenBuffer = shader->AsConstantBuffer("CB_TweenFrame");
	
	blendBuffer = new ConstantBuffer(&blendDesc, sizeof(BlendDesc) * MAX_MODEL_INSTANCE);
	sBlendBuffer = shader->AsConstantBuffer("CB_BlendFrame");

	instanceBuffer = new VertexBuffer(worlds, MAX_MODEL_INSTANCE, sizeof(Matrix), 1, true);
	
	// Create Compute Shader
	{
		computeShader = new Shader(L"71_GetMultiBones.fx");

		inputWorldBuffer = new StructuredBuffer(worlds, sizeof(Matrix), MAX_MODEL_INSTANCE);
		sInputWorldSRV = computeShader->AsSRV("InputWorlds");

		inputBoneBuffer = new StructuredBuffer(NULL, sizeof(Matrix), MAX_MODEL_TRANSFORMS);
		sInputBoneSRV = computeShader->AsSRV("InputBones");

		ID3D11Texture2D* texture;
		D3D11_TEXTURE2D_DESC desc;
		ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
		desc.Width = MAX_MODEL_TRANSFORMS * 4;
		desc.Height = MAX_MODEL_INSTANCE;
		desc.ArraySize = 1;
		desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
		desc.MipLevels = 1;
		desc.SampleDesc.Count = 1;
		Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &texture));

		outputBuffer = new TextureBuffer(texture);
		SafeRelease(texture);


		sOutputUAV = computeShader->AsUAV("Output");

		sTransformsSRV = computeShader->AsSRV("TransformsMap");
		sComputeTweenBuffer = computeShader->AsConstantBuffer("CB_TweenFrame");
		sComputeBlendBuffer = computeShader->AsConstantBuffer("CB_BlendFrame");
	}
}

일단 만들 쉐이더의 변수에 맞게 InputOutput값을 갖고온다.

그리고

if (texture == NULL)
{
	for (ModelMesh* mesh : model->Meshes())
	{
		mesh->SetShader(shader);
	}
	CreateTexture();


	Matrix bones[MAX_MODEL_TRANSFORMS];
	for (UINT i = 0; i < model->BoneCount(); i++)
	{
		bones[i] = model->BoneByIndex(i)->Transform();
	}
	inputBoneBuffer->CopyToInput(bones);
}

Update문에서 값을 갖고오게 바꿔준다.

void ModelAnimator::GetAttachTransform(UINT instance, Matrix * outResult)
{
	ID3D11Texture2D* texture = outputBuffer->Result();

	D3D11_MAPPED_SUBRESOURCE subResource;
	D3D::GetDC()->Map(texture, 0, D3D11_MAP_READ, 0, &subResource);
	{
		memcpy(outResult, (BYTE *)subResource.pData + (instance * subResource.RowPitch), sizeof(Matrix) * MAX_MODEL_TRANSFORMS);
	}
	D3D::GetDC()->Unmap(texture, 0);
}

현재 본의 위치를 instance로 바꿔서 갖고올 수 있게 해준다.

현재 받아온 데이터의 원하는 클립의 y축 좌표를 갖고 곱해서 갖고온다.

마지막으로

void ModelAnimator::UpdateTransforms()
{
	for (UINT i = 0; i < transforms.size(); i++)
		memcpy(worlds[i], transforms[i]->World(), sizeof(Matrix));

	D3D11_MAPPED_SUBRESOURCE subResource;
	D3D::GetDC()->Map(instanceBuffer->Buffer(), 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
	{
		memcpy(subResource.pData, worlds, sizeof(Matrix) * MAX_MESH_INSTANCE);
	}
	D3D::GetDC()->Unmap(instanceBuffer->Buffer(), 0);

	inputWorldBuffer->CopyToInput(worlds);
}

현재 Transform을 넘겨준 값을 갖고오고 위치를 업데이트 시켜준다.



DirectX Share Tweet +1