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?
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 was asking how to do a shadowmap generation(3 cascades) using a geometry shader.
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 ?