2,537
社区成员
发帖
与我相关
我的任务
分享
D3D11_TEXTURE2D_DESC tex2DDesc;
tex2DDesc.Height = hCount;
tex2DDesc.Width = wCount;
tex2DDesc.MipLevels = 1;
tex2DDesc.ArraySize = 1;
tex2DDesc.Format = DXGI_FORMAT_R32_FLOAT;
tex2DDesc.SampleDesc.Count = 1;
tex2DDesc.SampleDesc.Quality = 0;
tex2DDesc.Usage = D3D11_USAGE_DEFAULT;
tex2DDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
tex2DDesc.CPUAccessFlags = 0;
tex2DDesc.MiscFlags = 0;
// Set init data for both height maps to 0.0f
std::vector<float> vecInitHeight;
for (int i = 0; i < hCount*wCount; ++i)
{
vecInitHeight.push_back(0.0f);
}
D3D11_SUBRESOURCE_DATA subHeightData;
subHeightData.pSysMem = &vecInitHeight[0];
subHeightData.SysMemPitch = wCount*sizeof(float);
subHeightData.SysMemSlicePitch = hCount*wCount*sizeof(float);
// Sampled in VS to do transform
HR(device->CreateTexture2D(&tex2DDesc, &subHeightData, &mCurHeightMap));
HR(device->CreateTexture2D(&tex2DDesc, &subHeightData, &mLasHeightMap));
#define THREAD_NUM 32
#define MEM_SIZE (THREAD_NUM+2)
// Only need 3 params for CSUpdateHeight
cbuffer cbUpdateHeightPerObject
{
float gK1;
float gK2;
float gK3;
};
cbuffer cbUpdateNormAndTangPerObject
{
float gSpatialStep;
};
Texture2D<float> gCurTex;
RWTexture2D<float> gLasTex;
RWTexture2D<float2> gNormTex;
RWTexture2D<float2> gTangTex;
groupshared float gCache1[MEM_SIZE][MEM_SIZE]; //curtex
groupshared float gCache2[MEM_SIZE][MEM_SIZE]; //prevtex
int2 MaxInt2(int2 src, int2 border)
{
return int2(max(src.x, border.x), max(src.y, border.y));
}
int2 MinInt2(int2 src, int2 border)
{
return int2(min(src.x, border.x), min(src.y, border.y));
}
[numthreads(THREAD_NUM, THREAD_NUM, 1)]
void CSUpdateHeight(int3 groupThreadID:SV_GroupThreadID,
int3 dispatchThreadID : SV_DispatchThreadID)
{
// Update gCurTex data to gChache1
// Update gLasTex data to gCache2
// Clamp left up border
if (groupThreadID.x == 0 || groupThreadID.y == 0)
{
int2 xy0 = int2(dispatchThreadID.x - 1, dispatchThreadID.y - 1);//-1 needed?
int2 xy1 = int2(0, 0);
int2 xy = MaxInt2(xy0,int2(0,0));
gCache1[groupThreadID.x][groupThreadID.y] = gCurTex[xy];
gCache2[groupThreadID.x][groupThreadID.y] = gLasTex[xy];
}
// Clamp right down border
if (groupThreadID.x == (THREAD_NUM - 1) || groupThreadID.y == (THREAD_NUM - 1))//-1 needed?
{
int2 xy0 = int2(dispatchThreadID.x + 1, dispatchThreadID.y + 1);
int2 xy1 = int2(gCurTex.Length.x - 1, gCurTex.Length.y - 1);
int2 xy = MinInt2(xy0, xy1);
gCache1[groupThreadID.x + 2][groupThreadID.y + 2] = gCurTex[xy];
gCache2[groupThreadID.x + 2][groupThreadID.y + 2] = gLasTex[xy];
}
// Other
int2 xy0 = int2(gCurTex.Length.x - 1, gCurTex.Length.y - 1);
int2 xy = MinInt2(dispatchThreadID.xy, xy0);
gCache1[groupThreadID.x + 1][groupThreadID.y + 1] = gCurTex[xy];
gCache2[groupThreadID.x + 1][groupThreadID.y + 1] = gLasTex[xy];
// Wait for cache synchronize
GroupMemoryBarrierWithGroupSync();
int cx = groupThreadID.x + 1;
int cy = groupThreadID.y + 1;
// Restrict border from changing
if(dispatchThreadID.x!=0 &&
dispatchThreadID.y!=0 &&
dispatchThreadID.x<gCurTex.Length.x - 1 &&
dispatchThreadID.y<gCurTex.Length.y- 1)
gLasTex[dispatchThreadID.xy] =
gK1*gCache2[cx][cy] +
gK2*gCache1[cx][cy] +
gK3*(gCache1[cx + 1][cy] +
gCache1[cx - 1][cy] +
gCache1[cx][cy + 1] +
gCache1[cx][cy - 1]);
}
technique11 UpdateHeight
{
pass P0
{
SetVertexShader(NULL);
SetPixelShader(NULL);
SetComputeShader(CompileShader(cs_5_0, CSUpdateHeight()));
}
}
t += dt;
if (t >= mTimeStep)
{
++testcount;
// Update current and last height map
D3DX11_TECHNIQUE_DESC techDesc;
Effects::WavesUpdateFX->Test->GetDesc(&techDesc);
for (int p = 0; p < techDesc.Passes; ++p)
{
Effects::WavesUpdateFX->SetTestMap(mLasHeightSRV);
Effects::WavesUpdateFX->SetTestCount(testcount);
Effects::WavesUpdateFX->Test->GetPassByIndex(p)->Apply(0, dc);
int cxGroups = ceilf(1.0f * mNumRows / THREAD_NUM);
int cyGroups = ceilf(1.0f * mNumCols / THREAD_NUM);
HR(dc->Dispatch(cxGroups, cyGroups, 1));
ID3D11ShaderResourceView* clearSRVs[] = { NULL };
dc->CSSetShaderResources(0, 1, clearSRVs);
}
Effects::WavesUpdateFX->UpdateHeightTech->GetDesc(&techDesc);
for (int p = 0; p < techDesc.Passes; ++p)
{
Effects::WavesUpdateFX->SetK1(mK1);
Effects::WavesUpdateFX->SetK2(mK2);
Effects::WavesUpdateFX->SetK3(mK3);
Effects::WavesUpdateFX->SetCurTex(mCurHeightSRV);
Effects::WavesUpdateFX->SetLasTex(mLasHeightUAV);
Effects::WavesUpdateFX->UpdateHeightTech->GetPassByIndex(p)->Apply(0, dc);
int cxGroups = ceilf(1.0f * mNumRows / THREAD_NUM);
int cyGroups = ceilf(1.0f * mNumCols / THREAD_NUM);
HR(dc->Dispatch(cxGroups, cyGroups, 1));
}
// Good house keeping
ID3D11ShaderResourceView* clearSRVs[] = { NULL };
dc->CSSetShaderResources(0, 1, clearSRVs);
ID3D11UnorderedAccessView* clearUAVs[] = { NULL };
dc->CSSetUnorderedAccessViews(0, 1, clearUAVs, 0);
t = 0.0f;
}
dc->CSSetShader(0, 0, 0);