Well I've adopted the code in your QueryProfiling sample but I'm still having problems seeing anything in the shadow map.
When I look at it in PIX I'm getting nothing in the viewport preview window but it does show correctly inside the postVS window.
Maybe you (or someone else) can make out what my problem is : /
I'm going to post it in the order of execution:
void Renderer::RenderShadows()
{
// Set DepthStencilState (Z write)
this->deviceContext->OMSetDepthStencilState(this->depthEnabledStencilState, 0);
this->deviceContext->RSSetState(this->RS_Solid);
// Is the directional light casting shadows ?
if(this->lightManager->GetDominantDirectionalLight()->CanCastShadows())
{
this->shadows->RenderShadows(this->fsq, this->opaquePrimitives, this->opaqueModels,
this->pointTargetSampler, this->lightManager);
}
}
void Shadows::RenderShadows(FSQ* &fsq,
std::vector<Primitive*> primitiveList,
std::vector<ModelObject*> modelList,
ID3D11SamplerState* &amp;pointSampler,
LightManager* &amp;lightManager)
{
ID3D11DeviceContext* context = this->renderer->GetDeviceContext();
context->ClearDepthStencilView(this->shadowMapDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Set RenderTarget
context->OMSetRenderTargets(0, NULL, this->shadowMapDSV);
// Set Shader
context->VSSetShader(this->generateShadowMapShader->GetVS(), 0, 0);
context->PSSetShader(NULL, 0, 0);
// Cascade offsets
const XMFLOAT2 Offsets[4] =
{
XMFLOAT2(0.0f, 0.0f),
XMFLOAT2(0.5f, 0.0f),
XMFLOAT2(0.5f, 0.5f),
XMFLOAT2(0.0f, 0.5f)
};
const float sMapSize = static_cast<float>(shadowMapSize);
for(UINT cascadeIdx = 0; cascadeIdx < this->numCascades; ++cascadeIdx)
{
// Set viewport
D3D11_VIEWPORT viewport;
viewport.TopLeftX = Offsets[cascadeIdx].x * sMapSize * 2;
viewport.TopLeftY = Offsets[cascadeIdx].y * sMapSize * 2;
viewport.Width = static_cast<float>(sMapSize);
viewport.Height = viewport.Width;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
context->RSSetViewports(1, &amp;viewport);
lightManager->GetDominantDirectionalLight()->CalculateLightProjection(this->renderer->GetEngine()->GetCamera(),
cascadeIdx, sMapSize);
this->RenderDepth(primitiveList, modelList, lightManager);
// Set the blend state for opaque objects
context->OMSetBlendState(0, 0, 0xFFFFFFFF);
}
// Deferred shadow maps here...
// Set input and output off
ID3D11ShaderResourceView* NullResource = NULL;
ID3D11RenderTargetView* NullRT = NULL;
context->PSSetShaderResources(0, 1, &amp;NullResource);
context->OMSetRenderTargets(1, &amp;NullRT, NULL);
// Set back to original
context->RSSetViewports(1, &amp;this->renderer->graphicsDesc.viewport);
}
void DirectionalLight::CalculateLightProjection(BaseCamera* camera, UINT &amp;cascadeIdx,
const float &amp;sMapSize)
{
const float CascadeSplits[4] = { 0.125f, 0.25f, 0.5f, 1.0f};
const float Bias = 0.005f;
const float ShadowDist = 1.0f;
const float BackupDistance = 20.0f;
// Get the 8 points of the view frustum in world space
XMFLOAT3 corner[8];
XMVECTOR frustumCornersWS[8];
camera->ExtractFrustumCorner(corner);
for(UINT i = 0; i < 8; i++)
{
frustumCornersWS[i] = XMLoadFloat3(&amp;corner[i]);
}
float prevSplitDist = cascadeIdx == 0 ? 0.0f : CascadeSplits[cascadeIdx - 1] * ShadowDist;
float splitDist = CascadeSplits[cascadeIdx] * ShadowDist;
// Scale by the shadow view distance
for(UINT i = 0; i < 4; ++i)
{
XMVECTOR cornerRay = XMVectorSubtract(frustumCornersWS[i + 4], frustumCornersWS[i]);
XMVECTOR nearCornerRay = XMVectorScale(cornerRay, prevSplitDist);
XMVECTOR farCornerRay = XMVectorScale(cornerRay, splitDist);
frustumCornersWS[i + 4] = XMVectorAdd(frustumCornersWS[i], farCornerRay);
frustumCornersWS[i] = XMVectorAdd(frustumCornersWS[i], nearCornerRay);
}
// Calculate the centroid of the view frustum
XMVECTOR sphereCenterVec = XMVectorZero();
for(UINT i = 0; i < 8; ++i)
{
sphereCenterVec = XMVectorAdd(sphereCenterVec, frustumCornersWS[i]);
}
sphereCenterVec = XMVectorScale(sphereCenterVec, 1.0f / 8.0f);
// Calculate the radius of a bounding sphere
XMVECTOR sphereRadiusVec = XMVectorZero();
for(UINT i = 0; i < 8; ++i)
{
XMVECTOR dist = XMVector3Length(XMVectorSubtract(frustumCornersWS[i], sphereCenterVec));
sphereRadiusVec = XMVectorMax(sphereRadiusVec, dist);
}
sphereRadiusVec = XMVectorRound(sphereRadiusVec);
const float sphereRadius = XMVectorGetX(sphereRadiusVec);
const float backupDist = sphereRadius + camera->GetNearClip() + BackupDistance;
// Get Position of the shadow camera
XMVECTOR shadowCameraPosVec = sphereCenterVec;
XMVECTOR backupDirVec = XMLoadFloat3(&amp;this->direction);
backupDirVec = XMVectorScale(backupDirVec, backupDist);
shadowCameraPosVec = XMVectorAdd(shadowCameraPosVec, backupDirVec);
// Create Orthographic Projection
float nearClip = camera->GetNearClip();
XMMATRIX orthoProj = XMMatrixOrthographicOffCenterLH(-sphereRadius, sphereRadius, -sphereRadius, sphereRadius,
nearClip, backupDist + sphereRadius);
// Create View Matrix
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);
shadowCameraPosVec = XMVectorSetW(shadowCameraPosVec, 1.0f);
sphereCenterVec = XMVectorSetW(sphereCenterVec, 1.0f);
XMMATRIX lightView = XMMatrixLookAtLH(shadowCameraPosVec, sphereCenterVec, up);
// Create the rounding matrix, by projecting the world-space origin and determining
// the fractional offset in texel space
XMMATRIX shadowMatrix = lightView * orthoProj;
XMVECTOR shadowOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
shadowOrigin = XMVector4Transform(shadowOrigin, shadowMatrix);
shadowOrigin = XMVectorScale(shadowOrigin, sMapSize / 2.0f);
XMVECTOR roundedOrigin = XMVectorRound(shadowOrigin);
XMVECTOR roundOffset = XMVectorSubtract(roundedOrigin, shadowOrigin);
roundOffset = XMVectorScale(roundOffset, 2.0f / sMapSize);
roundOffset = XMVectorSetZ(roundOffset, 0.0f);
roundOffset = XMVectorSetW(roundOffset, 0.0f);
orthoProj.r[3] = XMVectorAdd(orthoProj.r[3], roundOffset);
shadowMatrix = lightView * orthoProj;
// Copy the data into the constant buffer
XMStoreFloat4x4(&amp;this->lightTransformProperties.ViewProjection, XMMatrixTranspose(shadowMatrix));
}
void ExtractFrustumCorner(XMFLOAT3* frustum)
{
// Get the 8 points of the view frustum in world space
XMVECTOR frustumCornersWS[8] =
{
XMVectorSet(-1.0f, 1.0f, 0.0f, 1.0f),
XMVectorSet( 1.0f, 1.0f, 0.0f, 1.0f),
XMVectorSet( 1.0f, -1.0f, 0.0f, 1.0f),
XMVectorSet(-1.0f, -1.0f, 0.0f, 1.0f),
XMVectorSet(-1.0f, 1.0f, 1.0f, 1.0f),
XMVectorSet( 1.0f, 1.0f, 1.0f, 1.0f),
XMVectorSet( 1.0f, -1.0f, 1.0f, 1.0f),
XMVectorSet(-1.0f, -1.0f, 1.0f, 1.0f),
};
XMMATRIX invViewProj = this->GetInverseViewProjectionNonTransposed();
for(UINT i = 0; i < 8; ++i)
{
frustumCornersWS[i] = XMVector3TransformCoord(frustumCornersWS[i], invViewProj);
}
for(int i = 0; i < 8; i++)
{
XMStoreFloat3(&amp;frustum[i], frustumCornersWS[i]);
}
}
void Shadows::RenderDepth(std::vector<Primitive*> primitiveList,
std::vector<ModelObject*> modelList,
LightManager* &amp;lightManager)
{
ID3D11DeviceContext* context = this->renderer->GetDeviceContext();
float blendFactor[4] = {1, 1, 1, 1};
context->OMSetBlendState(this->ColorWriteDisabledBlendState, blendFactor, 0xFFFFFFFF);
//*************************************************
// DIRECTIONAL LIGHT SOURCE (CASCADED SHADOW MAPS)
//*************************************************
ID3D11Buffer* constantBuffer = lightManager->GetDominantDirectionalLight()->GetLightTransformConstantBuffer();
// Go through each primitive
for(unsigned int i = 0; i < primitiveList.size(); i++)
{
// Set constant buffer
D3D11_MAPPED_SUBRESOURCE mappedResource;
// Lock the constant buffer so it can be written to
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
// Get a pointer to the data in the constant buffer.
cbLightTransformPropeties* pTransformData = (cbLightTransformPropeties*)mappedResource.pData;
// Copy the matrices into the constant buffer
pTransformData->World = primitiveList.at(i)->GetTransform();
pTransformData->ViewProjection = lightManager->GetDominantDirectionalLight()->GetLightTransformProperties().ViewProjection;
// Unlock the constant buffer
context->Unmap(constantBuffer, 0);
// Set constant buffer
context->VSSetConstantBuffers(0, 1, &amp;constantBuffer);
primitiveList.at(i)->Draw(context, true);
}
// Go through each model
for(unsigned int i = 0; i < modelList.size(); i++)
{
// Set constant buffer
D3D11_MAPPED_SUBRESOURCE mappedResource;
// Lock the constant buffer so it can be written to
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
// Get a pointer to the data in the constant buffer.
cbLightTransformPropeties* pTransformData = (cbLightTransformPropeties*)mappedResource.pData;
// Copy the matrices into the constant buffer
pTransformData->World = modelList.at(i)->GetTransform();
pTransformData->ViewProjection = lightManager->GetDominantDirectionalLight()->GetLightTransformProperties().ViewProjection;
// Unlock the constant buffer
context->Unmap(constantBuffer, 0);
// Set constant buffer
context->VSSetConstantBuffers(0, 1, &amp;constantBuffer);
modelList.at(i)->Draw(context, true);
}
//********************************************************************
}
I know this is quite a lot of code to go through but any help would be appreciated.