Jump to content

  • Log In with Google      Sign In   
  • Create Account

14 years ago on June 15th Gamedev.net was first launched! We want to thank all of you for being part of our community and hope the best years are ahead of us. Happy birthday Gamedev.net!

#Actuallipsryme

Posted 25 November 2012 - 07:50 AM

Well I've adopted the code in your QueryProfiling sample but I'm still having problems seeing anything in the shadow map.

Update: Okay so I've managed to get "something" on my texture. I still think there's something wrong with the viewport and the constant variables. Can someone explain what these variables do exactly ? And how I have to set them to get a correct image.

static const float ShadowDist = 1.0f;
static const float Backup = 20.0f; // -20.0f will give me an image
static const float NearClip = 1.0f;
static const float CascadeSplits[4] = { 0.125f, 0.25f, 0.5f, 1.0f };
static const float Bias = 0.005f;

#4lipsryme

Posted 25 November 2012 - 07:49 AM

Well I've adopted the code in your QueryProfiling sample but I'm still having problems seeing anything in the shadow map.

Update: Okay so I've managed to get "something" on my texture. I still think there's something wrong with the viewport and the constant variables. Can someone explain what these variables do exactly ? And how I have to set them to get a correct image.

static const float ShadowDist = 1.0f;
static const float Backup = 20.0f;
static const float NearClip = 1.0f;
static const float CascadeSplits[4] = { 0.125f, 0.25f, 0.5f, 1.0f };
static const float Bias = 0.005f;

#3lipsryme

Posted 24 November 2012 - 08:38 AM

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;amp;pointSampler,
	   LightManager* &amp;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;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;amp;NullResource);
context->OMSetRenderTargets(1, &amp;amp;NullRT, NULL);

// Set back to original
context->RSSetViewports(1, &amp;amp;this->renderer->graphicsDesc.viewport);
}


void DirectionalLight::CalculateLightProjection(BaseCamera* camera, UINT &amp;amp;cascadeIdx,
		    const float &amp;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;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;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;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;amp;frustum[i], frustumCornersWS[i]);
  }
}



void Shadows::RenderDepth(std::vector<Primitive*> primitiveList,
	    std::vector<ModelObject*> modelList,
	    LightManager* &amp;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;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;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;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;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.

#2lipsryme

Posted 24 November 2012 - 08:36 AM

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* &amp;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.

#1lipsryme

Posted 24 November 2012 - 08:29 AM

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* &pointSampler,
	   LightManager* &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, &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, &NullResource);
context->OMSetRenderTargets(1, &NullRT, NULL);
// Set back to original
context->RSSetViewports(1, &this->renderer->graphicsDesc.viewport);
}


void DirectionalLight::CalculateLightProjection(BaseCamera* camera, UINT &cascadeIdx,
		    const float &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(&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(&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(&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(&frustum[i], frustumCornersWS[i]);
  }
}



void Shadows::RenderDepth(std::vector<Primitive*> primitiveList,
	    std::vector<ModelObject*> modelList,
	    LightManager* &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, &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, &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, &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, &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.

PARTNERS