図1502a
このサンプルはフルサンプル305をコンピュートシェーダー(CS)を使う形に書き直したものです。
図1501b
この例のように、すでに記述した動きをCSを使って書き直すのも勉強になると思います。
1、データ入力用の配列 2、データ取得用の配列 3.CS入力用のエレメントバッファ 4、CS出力用のエレメントバッファ 5、3のビュー(シェーダーリソースビュー) 6、4のビュー(アクセスビュー) 7、リードバックバッファ
class PointsBall : public GameObject {
const UINT NUM_ELEMENTS = 64 * 32;
UINT m_NumVertices;
struct LocalData {
Vec4 m_LocalPosition;
Vec4 m_WorldPosition;
Vec4 m_Velocity;
UINT m_State[4];
LocalData() :
m_LocalPosition(0.0f),
m_WorldPosition(0.0f),
m_Velocity(0.0f)
{
for (auto& v : m_State) {
v = 0;
}
}
};
//エレメントバッファ
ComPtr<ID3D11Buffer> m_InBuffer;
ComPtr<ID3D11Buffer> m_OutBuffer;
//シェーダーリソースビュー
ComPtr<ID3D11ShaderResourceView> m_SRV;
//アクセスビュー
ComPtr < ID3D11UnorderedAccessView> m_UAV;
//リードバックバッファ
ComPtr<ID3D11Buffer> m_ReadBackBuffer;
vector<LocalData> m_LocalDataVec;
vector<LocalData> m_ResultDataVec;
vector<Mat4x4> m_MatVec;
//以下略
};
1、データ入力用の配列: m_LocalDataVec 2、データ取得用の配列: m_ResultDataVec 3.CS入力用のエレメントバッファ: m_InBuffer 4、CS出力用のエレメントバッファ: m_OutBuffer 5、1のビュー(シェーダーリソースビュー): m_SRV 6、2のビュー(アクセスビュー): m_UAV 7、リードバックバッファ: m_ReadBackBuffer
void PointsBall::OnCreate() {
vector<VertexPositionNormalTexture> vertices;
vector<uint16_t> indices;
m_LocalDataVec.resize(NUM_ELEMENTS);
//球体を作成
MeshUtill::CreateSphere(1.0f, 28, vertices, indices);
m_NumVertices = (UINT)vertices.size();
for (size_t i = 0; i < m_NumVertices; i++) {
LocalData tempLocalData;
tempLocalData.m_LocalPosition = vertices[i].position;
m_LocalDataVec[i] = tempLocalData;
}
m_ResultDataVec.resize(m_NumVertices);
//描画用メッシュの作成
float helfSize = 0.04f;
Col4 col(1.0f, 1.0f, 0.0f, 1.0f);
//頂点配列
vector<VertexPositionColorTexture> meshVertices = {
{ VertexPositionColorTexture(Vec3(-helfSize, helfSize, 0),col, Vec2(0.0f, 0.0f)) },
{ VertexPositionColorTexture(Vec3(helfSize, helfSize, 0),col, Vec2(1.0f, 0.0f)) },
{ VertexPositionColorTexture(Vec3(-helfSize, -helfSize, 0),col, Vec2(0.0f, 1.0f)) },
{ VertexPositionColorTexture(Vec3(helfSize, -helfSize, 0),col, Vec2(1.0f, 1.0f)) },
};
//インデックス配列
vector<uint16_t> meshIndex = { 0, 1, 2, 1, 3, 2 };
//2次元平面とする(頂点数が少ないため)
m_MeshRes = MeshResource::CreateMeshResource(meshVertices, meshIndex, true);
//全体の位置関連
auto ptrTransform = GetComponent<Transform>();
ptrTransform->SetScale(Vec3(m_Scale));
ptrTransform->SetRotation(Vec3(0));
ptrTransform->SetPosition(m_Position);
//描画コンポーネントの追加(インスタンス描画)
auto PtrDraw = AddComponent<PCTStaticInstanceDraw>();
PtrDraw->SetMeshResource(m_MeshRes);
PtrDraw->SetTextureResource(L"SPARK_TX");
PtrDraw->SetDepthStencilState(DepthStencilState::Read);
//各頂点ごとに行列を作成
for (size_t i = 0; i < m_NumVertices; i++) {
Mat4x4 tempMat;
tempMat.affineTransformation(
Vec3(1.0f),
Vec3(0.0f),
Vec3(0.0f),
m_LocalDataVec[i].m_LocalPosition
);
//インスタンス描画の行列として設定
PtrDraw->AddMatrix(tempMat);
}
SetAlphaActive(true);
auto Dev = App::GetApp()->GetDeviceResources();
auto pDx11Device = Dev->GetD3DDevice();
auto pID3D11DeviceContext = Dev->GetD3DDeviceContext();
//エレメンツバッファ
D3D11_BUFFER_DESC buffer_desc = { 0 };
buffer_desc.ByteWidth = NUM_ELEMENTS * sizeof(LocalData);
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
buffer_desc.StructureByteStride = sizeof(LocalData);
ThrowIfFailed(
pDx11Device->CreateBuffer(&buffer_desc, nullptr, &m_InBuffer),
L"m_InBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
ThrowIfFailed(
pDx11Device->CreateBuffer(&buffer_desc, nullptr, &m_OutBuffer),
L"m_OutBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
//シェーダーリソースビュー
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc = {};
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvbuffer_desc.Buffer.FirstElement = 0;
srvbuffer_desc.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
srvbuffer_desc.Buffer.ElementWidth = NUM_ELEMENTS;
ThrowIfFailed(
pDx11Device->CreateShaderResourceView(m_InBuffer.Get(), &srvbuffer_desc, &m_SRV),
L"m_SRV作成に失敗しました",
L"pDx11Device->CreateShaderResourceView()",
L"PointsBall::OnCreate()"
);
//アクセスビュー
D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc = {};
uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavbuffer_desc.Buffer.NumElements = NUM_ELEMENTS;
ThrowIfFailed(
pDx11Device->CreateUnorderedAccessView(m_OutBuffer.Get(), &uavbuffer_desc, &m_UAV),
L"m_UAV作成に失敗しました",
L"pDx11Device->CreateUnorderedAccessView()",
L"PointsBall::OnCreate()"
);
//リードバックバッファ
D3D11_BUFFER_DESC readback_buffer_desc = {};
readback_buffer_desc.ByteWidth = NUM_ELEMENTS * sizeof(LocalData);
readback_buffer_desc.Usage = D3D11_USAGE_STAGING;
readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
readback_buffer_desc.StructureByteStride = sizeof(LocalData);
ThrowIfFailed(
pDx11Device->CreateBuffer(&readback_buffer_desc, nullptr, &m_ReadBackBuffer),
L"m_ReadBackBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
}
m_LocalDataVec.resize(NUM_ELEMENTS);
//球体を作成
MeshUtill::CreateSphere(1.0f, 28, vertices, indices);
m_NumVertices = (UINT)vertices.size();
for (size_t i = 0; i < m_NumVertices; i++) {
LocalData tempLocalData;
tempLocalData.m_LocalPosition = vertices[i].position;
m_LocalDataVec[i] = tempLocalData;
}
m_ResultDataVec.resize(m_NumVertices);
//描画用メッシュの作成
float helfSize = 0.04f;
Col4 col(1.0f, 1.0f, 0.0f, 1.0f);
//頂点配列
vector<VertexPositionColorTexture> meshVertices = {
{ VertexPositionColorTexture(Vec3(-helfSize, helfSize, 0),col, Vec2(0.0f, 0.0f)) },
{ VertexPositionColorTexture(Vec3(helfSize, helfSize, 0),col, Vec2(1.0f, 0.0f)) },
{ VertexPositionColorTexture(Vec3(-helfSize, -helfSize, 0),col, Vec2(0.0f, 1.0f)) },
{ VertexPositionColorTexture(Vec3(helfSize, -helfSize, 0),col, Vec2(1.0f, 1.0f)) },
};
//インデックス配列
vector<uint16_t> meshIndex = { 0, 1, 2, 1, 3, 2 };
//2次元平面とする(頂点数が少ないため)
m_MeshRes = MeshResource::CreateMeshResource(meshVertices, meshIndex, true);
//全体の位置関連
auto ptrTransform = GetComponent<Transform>();
ptrTransform->SetScale(Vec3(m_Scale));
ptrTransform->SetRotation(Vec3(0));
ptrTransform->SetPosition(m_Position);
//描画コンポーネントの追加(インスタンス描画)
auto PtrDraw = AddComponent<PCTStaticInstanceDraw>();
PtrDraw->SetMeshResource(m_MeshRes);
PtrDraw->SetTextureResource(L"SPARK_TX");
PtrDraw->SetDepthStencilState(DepthStencilState::Read);
//各頂点ごとに行列を作成
for (size_t i = 0; i < m_NumVertices; i++) {
Mat4x4 tempMat;
tempMat.affineTransformation(
Vec3(1.0f),
Vec3(0.0f),
Vec3(0.0f),
m_LocalDataVec[i].m_LocalPosition
);
//インスタンス描画の行列として設定
PtrDraw->AddMatrix(tempMat);
}
SetAlphaActive(true);
auto Dev = App::GetApp()->GetDeviceResources();
auto pDx11Device = Dev->GetD3DDevice();
auto pID3D11DeviceContext = Dev->GetD3DDeviceContext();
//エレメンツバッファ
D3D11_BUFFER_DESC buffer_desc = { 0 };
buffer_desc.ByteWidth = NUM_ELEMENTS * sizeof(LocalData);
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
buffer_desc.StructureByteStride = sizeof(LocalData);
ThrowIfFailed(
pDx11Device->CreateBuffer(&buffer_desc, nullptr, &m_InBuffer),
L"m_InBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
ThrowIfFailed(
pDx11Device->CreateBuffer(&buffer_desc, nullptr, &m_OutBuffer),
L"m_OutBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
//シェーダーリソースビュー
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc = {};
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvbuffer_desc.Buffer.FirstElement = 0;
srvbuffer_desc.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
srvbuffer_desc.Buffer.ElementWidth = NUM_ELEMENTS;
ThrowIfFailed(
pDx11Device->CreateShaderResourceView(m_InBuffer.Get(), &srvbuffer_desc, &m_SRV),
L"m_SRV作成に失敗しました",
L"pDx11Device->CreateShaderResourceView()",
L"PointsBall::OnCreate()"
);
//アクセスビュー
D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc = {};
uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavbuffer_desc.Buffer.NumElements = NUM_ELEMENTS;
ThrowIfFailed(
pDx11Device->CreateUnorderedAccessView(m_OutBuffer.Get(), &uavbuffer_desc, &m_UAV),
L"m_UAV作成に失敗しました",
L"pDx11Device->CreateUnorderedAccessView()",
L"PointsBall::OnCreate()"
);
//リードバックバッファ
D3D11_BUFFER_DESC readback_buffer_desc = {};
readback_buffer_desc.ByteWidth = NUM_ELEMENTS * sizeof(LocalData);
readback_buffer_desc.Usage = D3D11_USAGE_STAGING;
readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
readback_buffer_desc.StructureByteStride = sizeof(LocalData);
ThrowIfFailed(
pDx11Device->CreateBuffer(&readback_buffer_desc, nullptr, &m_ReadBackBuffer),
L"m_ReadBackBuffer作成に失敗しました",
L"pDx11Device->CreateBuffer()",
L"PointsBall::OnCreate()"
);
void PointsBall::OnUpdate() {
float elapsedTime = App::GetApp()->GetElapsedTime();
auto ptrDraw = GetComponent<PCTStaticInstanceDraw>();
auto ptrTransform = GetComponent<Transform>();
//全体を回転させる
auto worldQt = ptrTransform->GetQuaternion();
Quat spanQt(Vec3(0, 1, 0), elapsedTime);
worldQt *= spanQt;
ptrTransform->SetQuaternion(worldQt);
auto Dev = App::GetApp()->GetDeviceResources();
auto pID3D11DeviceContext = Dev->GetD3DDeviceContext();
CB cb = {};
auto playerSh = GetStage()->GetSharedGameObject<Player>(L"Player");
cb.m_PlayerPosition = playerSh->GetComponent<Transform>()->GetWorldPosition();
cb.m_PlayerPosition.w = 1.0f;
cb.m_WorldMatrix = ptrTransform->GetWorldMatrix();
// paramf[0] == elapsedTime
// paramf[1] == velocityPower
// paramf[2] == gravity_y
// paramf[3] == baseY
cb.paramf[0] = elapsedTime;
cb.paramf[1] = 3.0f;
cb.paramf[2] = -9.8f;
cb.paramf[3] = m_Scale * 0.02f;
ID3D11Buffer* pConstantBuffer = ConstantBufferCalcbody::GetPtr()->GetBuffer();
pID3D11DeviceContext->UpdateSubresource(pConstantBuffer, 0, nullptr, &cb, 0, 0);
pID3D11DeviceContext->CSSetConstantBuffers(0, 1, &pConstantBuffer);
pID3D11DeviceContext->CSSetShader(ComputeSaderCalcbody::GetPtr()->GetShader(), nullptr, 0);
pID3D11DeviceContext->UpdateSubresource(m_InBuffer.Get(), 0, nullptr, &m_LocalDataVec[0], 0, 0);
pID3D11DeviceContext->CSSetShaderResources(0, 1, m_SRV.GetAddressOf());
pID3D11DeviceContext->CSSetUnorderedAccessViews(0, 1, m_UAV.GetAddressOf(), nullptr);
pID3D11DeviceContext->Dispatch((UINT)m_NumVertices, 1, 1);
//カメラのレイを作成しておく
auto camera = OnGetDrawCamera();
auto lay = camera->GetAt() - camera->GetEye();
lay.normalize();
Quat qtCamera;
//回転は常にカメラを向くようにする
qtCamera.facing(lay);
//結果の読み取り
D3D11_MAPPED_SUBRESOURCE MappedResource = { 0 };
pID3D11DeviceContext->CopyResource(m_ReadBackBuffer.Get(), m_OutBuffer.Get());
if (SUCCEEDED(pID3D11DeviceContext->Map(m_ReadBackBuffer.Get(), 0, D3D11_MAP_READ, 0, &MappedResource)))
{
memcpy(&m_ResultDataVec[0], MappedResource.pData, m_NumVertices * sizeof(LocalData));
pID3D11DeviceContext->Unmap(m_ReadBackBuffer.Get(), 0);
//行列の配列をクリア
m_MatVec.clear();
Mat4x4 worldMat;
for (auto& v : m_ResultDataVec) {
worldMat.affineTransformation(
Vec3(m_Scale),
Vec3(0.0f),
qtCamera,
v.m_WorldPosition
);
m_MatVec.push_back(worldMat);
}
//インスタンス行列の更新
ptrDraw->UpdateMultiMatrix(m_MatVec);
//結果を次の入力にコピー
for (size_t i = 0; i < m_ResultDataVec.size(); i++) {
m_LocalDataVec[i] = m_ResultDataVec[i];
}
}
// CSの開放
ID3D11UnorderedAccessView* ppUAViewNULL[1] = { nullptr };
pID3D11DeviceContext->CSSetUnorderedAccessViews(0, 1, ppUAViewNULL, nullptr);
ID3D11ShaderResourceView* ppSRVNULL[1] = { nullptr };
pID3D11DeviceContext->CSSetShaderResources(0, 1, ppSRVNULL);
}
float elapsedTime = App::GetApp()->GetElapsedTime();
auto ptrDraw = GetComponent<PCTStaticInstanceDraw>();
auto ptrTransform = GetComponent<Transform>();
//全体を回転させる
auto worldQt = ptrTransform->GetQuaternion();
Quat spanQt(Vec3(0, 1, 0), elapsedTime);
worldQt *= spanQt;
ptrTransform->SetQuaternion(worldQt);
auto Dev = App::GetApp()->GetDeviceResources();
auto pID3D11DeviceContext = Dev->GetD3DDeviceContext();
1、プレイヤーのワールド位置 2、球全体のワールド行列 3、前ターンからの時間(elapsedTime) 4、プレイヤーと当たったときのはじける強さ(velocityPower) 5、重力係数(gravity_y) 6、最終落下位置(baseY)
CB cb = {};
auto playerSh = GetStage()->GetSharedGameObject<Player>(L"Player");
cb.m_PlayerPosition = playerSh->GetComponent<Transform>()->GetWorldPosition();
cb.m_PlayerPosition.w = 1.0f;
cb.m_WorldMatrix = ptrTransform->GetWorldMatrix();
// paramf[0] == elapsedTime
// paramf[1] == velocityPower
// paramf[2] == gravity_y
// paramf[3] == baseY
cb.paramf[0] = elapsedTime;
cb.paramf[1] = 3.0f;
cb.paramf[2] = -9.8f;
cb.paramf[3] = m_Scale * 0.02f;
ID3D11Buffer* pConstantBuffer = ConstantBufferCalcbody::GetPtr()->GetBuffer();
pID3D11DeviceContext->UpdateSubresource(pConstantBuffer, 0, nullptr, &cb, 0, 0);
pID3D11DeviceContext->CSSetConstantBuffers(0, 1, &pConstantBuffer);
pID3D11DeviceContext->CSSetShader(ComputeSaderCalcbody::GetPtr()->GetShader(), nullptr, 0);
pID3D11DeviceContext->UpdateSubresource(m_InBuffer.Get(), 0, nullptr, &m_LocalDataVec[0], 0, 0);
pID3D11DeviceContext->CSSetShaderResources(0, 1, m_SRV.GetAddressOf());
pID3D11DeviceContext->CSSetUnorderedAccessViews(0, 1, m_UAV.GetAddressOf(), nullptr);
pID3D11DeviceContext->Dispatch((UINT)m_NumVertices, 1, 1);
1、各点のローカルデータをワールド位置に座標変換 2、もしプレイヤーが当たったら飛び出す処理 3、地面についてらもう動かなくなる処理 3、最終的に各点のワールドポジションを出力する
//--------------------------------------------------------------------------------------
// コンスタントバッファ
//--------------------------------------------------------------------------------------
cbuffer CB : register(b0)
{
row_major float4x4 g_world;
float4 g_playerPosition;
float4 g_paramf;
// g_paramf[0] == elapsedTime
// g_paramf[1] == velocityPower
// g_paramf[2] == gravity_y
// g_paramf[3] == baseY
};
//--------------------------------------------------------------------------------------
// 各点のデータ
//--------------------------------------------------------------------------------------
struct LocalData {
float4 m_LocalPosition;
float4 m_WorldPosition;
float4 m_Velocity;
uint4 m_State;
};
//シェーダリソースビュー
StructuredBuffer<LocalData> inPosVelo : register(t0);
//アクセスビュー
RWStructuredBuffer<LocalData> outPosVelo : register(u0);
[numthreads(64, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
//入力からデータをして出力にコピー
outPosVelo[DTid.x].m_LocalPosition = inPosVelo[DTid.x].m_LocalPosition;
outPosVelo[DTid.x].m_LocalPosition.w = 1.0;
outPosVelo[DTid.x].m_State = inPosVelo[DTid.x].m_State;
uint state = outPosVelo[DTid.x].m_State.x;
if (state == 2) {
//落下した時以外はワールド位置を計算
outPosVelo[DTid.x].m_WorldPosition = inPosVelo[DTid.x].m_WorldPosition;
}
else {
//落下した時以外はワールド位置を計算
outPosVelo[DTid.x].m_WorldPosition = mul(outPosVelo[DTid.x].m_LocalPosition, g_world);
}
outPosVelo[DTid.x].m_Velocity = inPosVelo[DTid.x].m_Velocity;
//ステートをチェックして場合によってはワールドポジションを変更
float baseY = g_paramf[3];
float velocityPower = g_paramf[1];
float4 gravity = float4(0, g_paramf[2], 0,0);
float elapsedTime = g_paramf[0];
float3 playerPos = float3(g_playerPosition.xyz);
float3 targetPos = float3(outPosVelo[DTid.x].m_WorldPosition.xyz);
if (state == 0) {
float len = length(playerPos - targetPos);
if (len < 0.4f) {
//lenが0.4未満なら衝突してると判断
//ステートを変更
//衝突していたら球から飛び出すように速度を設定
outPosVelo[DTid.x].m_State.x = 1;
float3 velo = playerPos - targetPos;
outPosVelo[DTid.x].m_Velocity.xyz = velo.xyz;
outPosVelo[DTid.x].m_Velocity.w = 0.0;
normalize(outPosVelo[DTid.x].m_Velocity);
outPosVelo[DTid.x].m_Velocity.y = 1.0f;
outPosVelo[DTid.x].m_Velocity *= velocityPower;
}
}
else if (state == 1) {
//飛び散る状態
if (targetPos.y <= baseY) {
//落下終了
outPosVelo[DTid.x].m_State.x = 2;
outPosVelo[DTid.x].m_WorldPosition.y = baseY;
}
else {
//落下中
outPosVelo[DTid.x].m_Velocity += gravity * elapsedTime;
outPosVelo[DTid.x].m_LocalPosition += outPosVelo[DTid.x].m_Velocity * elapsedTime;
outPosVelo[DTid.x].m_LocalPosition.w = 1.0;
outPosVelo[DTid.x].m_WorldPosition = mul(outPosVelo[DTid.x].m_LocalPosition, g_world);
}
}
}
cbuffer CB : register(b0)
{
row_major float4x4 g_world;
float4 g_playerPosition;
float4 g_paramf;
// g_paramf[0] == elapsedTime
// g_paramf[1] == velocityPower
// g_paramf[2] == gravity_y
// g_paramf[3] == baseY
};
//--------------------------------------------------------------------------------------
// 各点のデータ
//--------------------------------------------------------------------------------------
struct LocalData {
float4 m_LocalPosition;
float4 m_WorldPosition;
float4 m_Velocity;
uint4 m_State;
};
//シェーダリソースビュー
StructuredBuffer<LocalData> inPosVelo : register(t0);
//アクセスビュー
RWStructuredBuffer<LocalData> outPosVelo : register(u0);
0: 回転状態 1: プレイヤーと当たって落ちる状態 2: 落下後の状態
[numthreads(64, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
[numthreads(1, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
//入力からデータをして出力にコピー
outPosVelo[DTid.x].m_LocalPosition = inPosVelo[DTid.x].m_LocalPosition;
outPosVelo[DTid.x].m_LocalPosition.w = 1.0;
outPosVelo[DTid.x].m_State = inPosVelo[DTid.x].m_State;
//カメラのレイを作成しておく
auto camera = OnGetDrawCamera();
auto lay = camera->GetAt() - camera->GetEye();
lay.normalize();
Quat qtCamera;
//回転は常にカメラを向くようにする
qtCamera.facing(lay);
//結果の読み取り
D3D11_MAPPED_SUBRESOURCE MappedResource = { 0 };
pID3D11DeviceContext->CopyResource(m_ReadBackBuffer.Get(), m_OutBuffer.Get());
if (SUCCEEDED(pID3D11DeviceContext->Map(m_ReadBackBuffer.Get(), 0, D3D11_MAP_READ, 0, &MappedResource)))
{
memcpy(&m_ResultDataVec[0], MappedResource.pData, m_NumVertices * sizeof(LocalData));
pID3D11DeviceContext->Unmap(m_ReadBackBuffer.Get(), 0);
//行列の配列をクリア
m_MatVec.clear();
Mat4x4 worldMat;
for (auto& v : m_ResultDataVec) {
worldMat.affineTransformation(
Vec3(m_Scale),
Vec3(0.0f),
qtCamera,
v.m_WorldPosition
);
m_MatVec.push_back(worldMat);
}
//インスタンス行列の更新
ptrDraw->UpdateMultiMatrix(m_MatVec);
//結果を次の入力にコピー
for (size_t i = 0; i < m_ResultDataVec.size(); i++) {
m_LocalDataVec[i] = m_ResultDataVec[i];
}
}
// CSの開放
ID3D11UnorderedAccessView* ppUAViewNULL[1] = { nullptr };
pID3D11DeviceContext->CSSetUnorderedAccessViews(0, 1, ppUAViewNULL, nullptr);
ID3D11ShaderResourceView* ppSRVNULL[1] = { nullptr };
pID3D11DeviceContext->CSSetShaderResources(0, 1, ppSRVNULL);
pID3D11DeviceContext->CopyResource(m_ReadBackBuffer.Get(), m_OutBuffer.Get());
if (SUCCEEDED(pID3D11DeviceContext->Map(m_ReadBackBuffer.Get(), 0, D3D11_MAP_READ, 0, &MappedResource)))
{
memcpy(&m_ResultDataVec[0], MappedResource.pData, m_NumVertices * sizeof(LocalData));
//行列の配列をクリア
m_MatVec.clear();
Mat4x4 worldMat;
for (auto& v : m_ResultDataVec) {
worldMat.affineTransformation(
Vec3(m_Scale),
Vec3(0.0f),
qtCamera,
v.m_WorldPosition
);
m_MatVec.push_back(worldMat);
}
//インスタンス行列の更新
ptrDraw->UpdateMultiMatrix(m_MatVec);
//インスタンス行列の更新
ptrDraw->UpdateMultiMatrix(m_MatVec);
//結果を次の入力にコピー
for (size_t i = 0; i < m_ResultDataVec.size(); i++) {
m_LocalDataVec[i] = m_ResultDataVec[i];
}