I'm following https://www.ea.com/frostbite/news/shadows-decals-d3d10-techniques-from-frostbite The slide also gives the hlsl code. But the problem is CPU side coding. can anyone tell me how to do that?
🎉 Celebrating 25 Years of GameDev.net! 🎉
Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!
How to use GS for shadowmap generation(CSM)?
ok u will need to learn how to use a geomshader:
https://takinginitiative.wordpress.com/2011/01/12/directx10-tutorial-9-the-geometry-shader/
or this
https://www.braynzarsoft.net/viewtutorial/q16390-36-billboarding-geometry-shader
then u can modify these apps to do csm (u can pass yr data and cascade in the shader); i assume that u know the theory behind csm, if not, here is a good guide:
http://ogldev.atspace.co.uk/www/tutorial49/tutorial49.html
bear in mind that the frostbite version is not what you're going to end up with at first, but u will definitely gain cpu speed but at first it is likely that u will be gpu bound. U will need to transfer your culler data to the geomshader but I'll let u optimise it ?
That's it … all the best ?
I currently create shadow map textures separately (3 cascade - 3 textures) When I render the depth for 3 cascades I do the following.
descTex2D.MiscFlags = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateTexture2D(&descTex2D, NULL, &RE_D3D11_CSM[0])))
{
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
SecureZeroMemory(&dsvDesc, sizeof(dsvDesc));
dsvDesc.Flags = 0;
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Texture2D.MipSlice = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateDepthStencilView(RE_D3D11_CSM[0], &dsvDesc, &RE_D3D11_CSM_DSV[0])))
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
SecureZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = descTex2D.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateShaderResourceView(RE_D3D11_CSM[0], &srvDesc, &RE_D3D11_CSM_SRV[0])))
{
RE_D3D11_CSM_VP[0].TopLeftX = RE_D3D11_CSM_VP[0].TopLeftY = 0;
RE_D3D11_CSM_VP[0].Height = 4096;
RE_D3D11_CSM_VP[0].Width = 4096;
RE_D3D11_CSM_VP[0].MinDepth = 0.0f;
RE_D3D11_CSM_VP[0].MaxDepth = 1.0f;
}
}
}
D3D11_TEXTURE2D_DESC descTex2D;
SecureZeroMemory(&descTex2D, sizeof(descTex2D));
descTex2D.Usage = D3D11_USAGE_DEFAULT;
descTex2D.Format = DXGI_FORMAT_R32_TYPELESS;
descTex2D.Width = 3072
descTex2D.Height = 3072;
descTex2D.SampleDesc.Count = 1;
descTex2D.SampleDesc.Quality = 0;
descTex2D.MipLevels = 1;
descTex2D.ArraySize = 1;
descTex2D.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
descTex2D.CPUAccessFlags = 0;
descTex2D.MiscFlags = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateTexture2D(&descTex2D, NULL, &RE_D3D11_CSM[1])))
{
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
SecureZeroMemory(&dsvDesc, sizeof(dsvDesc));
dsvDesc.Flags = 0;
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Texture2D.MipSlice = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateDepthStencilView(RE_D3D11_CSM[1], &dsvDesc, &RE_D3D11_CSM_DSV[1])))
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
SecureZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = descTex2D.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
if (SUCCEEDED(hr = RE_D3D11_Device->CreateShaderResourceView(RE_D3D11_CSM[1], &srvDesc, &RE_D3D11_CSM_SRV[1])))
{
RE_D3D11_CSM_VP[1].TopLeftX = RE_D3D11_CSM_VP[1].TopLeftY = 0;
RE_D3D11_CSM_VP[1].Height = 3072;
RE_D3D11_CSM_VP[1].Width = 3072;
RE_D3D11_CSM_VP[1].MinDepth = 0.0f;
RE_D3D11_CSM_VP[1].MaxDepth = 1.0f;
}
}
}
etc...
for (int i=0; i<3; i++)
{
RE_D3D11_ImmediateContext->RSSetViewports(1, &RE_D3D11_CSM_VP[i]);
RE_D3D11_ImmediateContext->OMSetRenderTargets(0, &NULLRTV, RE_D3D11_CSM_DSV[i]);
RE_D3D11_ImmediateContext->ClearDepthStencilView(RE_D3D11_CSM_DSV[i], D3D11_CLEAR_DEPTH, 1.0f, 0);
mytest->CSM_GetLightViewProjection(i, mycam, RE_LightDirection, mLightViewProjection[i]);
mytest->DrawCSM(RE_D3D11_ImmediateContext, RE_D3D11_SamplerState_Main, XMMatrixIdentity());
RE_D3D11_ImmediateContext->OMSetRenderTargets(0, &NULLRTV, NULLDSV);
}
I just want to know how to create the shadowmap texture(Is it a single one or separate 3 textures) for geometry shader single pass shadowmap generation. I have a little understanding about GS. What I cant understand is the CPU side coding parts(how to set viewports, render targets). Is it the same for my prev implementation? Take a peek at the below
I just want to know how to create the shadowmap texture(Is it a single one or separate 3 textures)
it is 1 texture with all 3 in it ?
shadowmapTexture is a texture array i.e. it is the same type as one of your RE_D3D11_CSM[i];
sliceCount is the number of textures that shadowmapTexture was initialised with;
so in your case sliceCount is 3;
view is the same type of as one of your RE_D3D11_CSM_DSV[i];
and it is this view that you pass to the shader;
so essentially you need these 3 variables 1 shadowmapTexture using CreateTexture2D with empty textures but , 1 slicecount, and 1 view:
// pseudo
******
STEP 1
******
std::vector<byte*> maps;
// create 3 empties and fill with 0s
// make sure that u use the correct byte count to match the GS, i leave that to u as an exercise to find out
maps[0] to [2] = new byte[ width x height ]
std::vector<D3D_subresource_data> initialdata;
i = 0
for (auto m : maps)
{
D3D11_SUBRESOURCE_DATA srd;
srd.pSysMem = maps[i++]
srd.... // fill init data appropriately
initialdata.emplace_back(srd)
}
D3D11_TEXTURE2D_DESC desc;
desc.BindFlags = ..BIND_SHADER_RESOURCE | ..BIND_RENDER_TARGET // please check properly one or both
sliceCount = desc.ArraySize = maps.size()
desc.... // fill the rest appropriately
ID3D11Txture* shadowmapTexture = nullptr
CreateTexture2D(desc, initialdata.data(), &shadowmapTexture)
ID3D11ShaderResourceView* view = nullptr;
********************************************************************
STEP 2 now create the texture array view like on the slide you show
********************************************************************
Step 3 pass to shader
Step 4 remove your for-loop from the c++ as it will be done for you in the gs
Step 5 call shader
I have already given u some links to see how to pass these as input to the geom shader. If u don't know how the geomshader works than honestly speaking you should not use it until you learn how to. It's like trying to drive a lorry without proper lessons, right ?
ok so i've done this from the top of my head, please tidy up and that should get u going.
That's it, u have all u need now … all the best ?