Jump to content
  • Advertisement
Sign in to follow this  
troyle

Strange soft shadow shader errors

This topic is 636 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been implementing soft shadows into my game engine and it all looks ok in the beginning...

https://puu.sh/rQ7Sr/54be0efbc3.png

 

But when I rotate the camera I get this...

https://puu.sh/rQ7yG/8cd692aaab.png

When I move around I also see that the shadow is offset from the model...

https://puu.sh/rQ7B9/6f988749d9.png

 

Has anyone seen this before or would be able to find out what the issue is?

I think it has something to do with the view matrix of the camera or something like that?

 

For my soft shadows I do 5 passes:


  1. Render the scene from the cameras POV to a texture

  2. Render that texture as black and white

  3. Downscale that texture to half its size

  4. Blur the texture (blurring the shadows edges)

  5. Upscale the texture back to normal size


I have checked back and all the matrices get updated per frame

 

EDIT: Added code

Render Light To Texture

bool CGraphics::RenderToTexture()
{
D3DXMATRIX worldMatrix,lightViewMatrix,lightProjMatrix;

bool result;
CMesh* tempMesh = nullptr;

m_ToTexture->SetRenderTarget(m_Device->GetDeviceContext());
m_ToTexture->ClearRenderTarget(m_Device->GetDeviceContext(), 0.0f,0.0f,1.0f,1.0f);

m_PointLights[0]->GenerateViewMatrix();

m_Device->GetWorldMatrix(worldMatrix);

m_PointLights[0]->GetViewMatrix(lightViewMatrix);
m_PointLights[0]->GetProjMatrix(lightProjMatrix);

for(int i = 0;i<m_NumModels;i++)
{
D3DXVECTOR3 tempPos = m_Models[i]->GetPosition();
D3DXMatrixTranslation(&worldMatrix,tempPos.x,tempPos.y,tempPos.z);

result = true;//m_Frustrum->CheckSphere(position.x,position.y,position.z,2.0f);

if(result)
{
m_Models[i]->GetMatrix(worldMatrix);
tempMesh = m_Models[i]->GetMesh();
tempMesh->Render(m_Device->GetDeviceContext());

result = m_DepthShader->Render(m_Device->GetDeviceContext(),tempMesh->GetIndexCount(),
worldMatrix,lightViewMatrix,lightProjMatrix);
if(!result) return false;

m_Device->GetWorldMatrix(worldMatrix);
}
}

m_Device->SetBackBufferTarget();
m_Device->ResetViewport();

return true;
}

Render the shadows in black and white

bool CGraphics::RenderBW()
{
D3DXMATRIX worldMatrix,viewMatrix,projMatrix,lightViewMatrix,lightProjMatrix;

bool result;
CMesh* tempMesh = nullptr;

m_BWTexture->SetRenderTarget(m_Device->GetDeviceContext());
m_BWTexture->ClearRenderTarget(m_Device->GetDeviceContext(),0.0f,0.0f,1.0f,1.0f);

m_Cameras[0]->Update();

m_PointLights[0]->GenerateViewMatrix();

m_Cameras[0]->GetViewMatrix(viewMatrix);
m_Device->GetWorldMatrix(worldMatrix);
m_Device->GetProjMatrix(projMatrix);

m_PointLights[0]->GetViewMatrix(lightViewMatrix);
m_PointLights[0]->GetProjMatrix(lightProjMatrix);

for(int i = 0;i<m_NumModels;i++)
{
D3DXVECTOR3 tempPos = m_Models[i]->GetPosition();
D3DXMatrixTranslation(&worldMatrix,tempPos.x,tempPos.y,tempPos.z);

result = true;//m_Frustrum->CheckSphere(position.x,position.y,position.z,2.0f);

if(result)
{
m_Models[i]->GetMatrix(worldMatrix);
tempMesh = m_Models[i]->GetMesh();
tempMesh->Render(m_Device->GetDeviceContext());

result = m_ShadowShader->Render(m_Device->GetDeviceContext(),tempMesh->GetIndexCount(),
worldMatrix,viewMatrix,projMatrix,lightViewMatrix,lightProjMatrix,
m_ToTexture->GetShaderResourceView(),m_PointLights[0]->GetPosition());
if(!result) return false;

m_Device->GetWorldMatrix(worldMatrix);
}
}

m_Device->SetBackBufferTarget();
m_Device->ResetViewport();

return true;
}

Downscale the texture to half

bool CGraphics::DownScale()
{
D3DXMATRIX worldMatrix,baseViewMatrix,orthoMatrix;
bool result;

m_DownScale->SetRenderTarget(m_Device->GetDeviceContext());

m_DownScale->ClearRenderTarget(m_Device->GetDeviceContext(),0.0f,0.0f,0.0f,1.0f);

m_Cameras[0]->Update();

m_Device->GetWorldMatrix(worldMatrix);
m_Cameras[0]->GetBaseViewMatrix(baseViewMatrix);

// Get the ortho matrix from the render to texture since texture has different dimensions being that it is smaller.
m_DownScale->GetOrthoMatrix(orthoMatrix);

m_Device->ZBufferOff();

m_DownSampleWindow->Render(m_Device->GetDeviceContext());
result = m_TextureShader->Render(m_Device->GetDeviceContext(),m_DownSampleWindow->GetIndexCount(),
worldMatrix,baseViewMatrix,orthoMatrix,m_BWTexture->GetShaderResourceView());

m_Device->ZBufferOn();

m_Device->SetBackBufferTarget();

m_Device->ResetViewport();

return true;
}

Blur Width

bool CGraphics::BlurTextureX()
{
D3DXMATRIX worldMatrix,baseViewMatrix,orthoMatrix;
float screenX;
bool result;

screenX = (float)(SHADOWMAP_WIDTH / 2);

m_BlurTextureX->SetRenderTarget(m_Device->GetDeviceContext());

m_BlurTextureX->ClearRenderTarget(m_Device->GetDeviceContext(),0.0f,0.0f,0.0f,1.0f);

m_Cameras[0]->Update();

m_Cameras[0]->GetBaseViewMatrix(baseViewMatrix);
m_Device->GetWorldMatrix(worldMatrix);

m_BlurTextureX->GetOrthoMatrix(orthoMatrix);

m_Device->ZBufferOff();

m_DownSampleWindow->Render(m_Device->GetDeviceContext());

// Render the small ortho window using the horizontal blur shader and the down sampled render to texture resource.
result = m_BlurShaderX->Render(m_Device->GetDeviceContext(),m_DownSampleWindow->GetIndexCount(),worldMatrix,baseViewMatrix,orthoMatrix,
m_DownScale->GetShaderResourceView(),screenX);
if(!result) return false;

m_Device->ZBufferOn();

m_Device->SetBackBufferTarget();
m_Device->ResetViewport();

return true;
}

Blur Height

bool CGraphics::BlurTextureY()
{
D3DXMATRIX worldMatrix,baseViewMatrix,orthoMatrix;
float screenY;
bool result;

screenY = (float)(SHADOWMAP_HEIGHT / 2);

m_BlurTextureY->SetRenderTarget(m_Device->GetDeviceContext());

m_BlurTextureY->ClearRenderTarget(m_Device->GetDeviceContext(),0.0f,0.0f,0.0f,1.0f);

m_Cameras[0]->Update();

m_Cameras[0]->GetBaseViewMatrix(baseViewMatrix);
m_Device->GetWorldMatrix(worldMatrix);

m_BlurTextureY->GetOrthoMatrix(orthoMatrix);

m_Device->ZBufferOff();

m_DownSampleWindow->Render(m_Device->GetDeviceContext());

// Render the small ortho window using the horizontal blur shader and the down sampled render to texture resource.
result = m_BlurShaderY->Render(m_Device->GetDeviceContext(),m_DownSampleWindow->GetIndexCount(),worldMatrix,baseViewMatrix,orthoMatrix,
m_BlurTextureX->GetShaderResourceView(),screenY);
if(!result) return false;

m_Device->ZBufferOn();

m_Device->SetBackBufferTarget();
m_Device->ResetViewport();

return true;
}

Rescale to full size

bool CGraphics::UpScale()
{
D3DXMATRIX worldMatrix,baseViewMatrix,orthoMatrix;
bool result;

m_UpScale->SetRenderTarget(m_Device->GetDeviceContext());

m_UpScale->ClearRenderTarget(m_Device->GetDeviceContext(),0.0f,0.0f,0.0f,1.0f);

m_Cameras[0]->GetBaseViewMatrix(baseViewMatrix);
m_Device->GetWorldMatrix(worldMatrix);

// Get the ortho matrix from the render to texture since texture has different dimensions.
m_UpScale->GetOrthoMatrix(orthoMatrix);

m_Device->ZBufferOff();

m_FullScreenWindow->Render(m_Device->GetDeviceContext());

// Render the full screen ortho window using the texture shader and the small sized final blurred render to texture resource.
result = m_TextureShader->Render(m_Device->GetDeviceContext(),m_FullScreenWindow->GetIndexCount(),
worldMatrix,baseViewMatrix,orthoMatrix,m_BlurTextureY->GetShaderResourceView());
if(!result) return false;

m_Device->ZBufferOn();

m_Device->SetBackBufferTarget();

m_Device->ResetViewport();

return true;
}

Share this post


Link to post
Share on other sites
Advertisement

Hello,

 

Some thoughts off the top of my head. Not sure if they apply, but let's see if they stick. When you say, "Render the scene from the cameras POV", are you referring to the player camera, or a camera that is positioned in the perspective of the light source? It just seems a trifle odd when you adjust your player camera, it would affect the, "light camera". Unless of course your player is holding a flashlight, or something similar.

 

Also, the issue your seeing with the shadow looks to me to be, "Peter Panning". Are you building this shadow map from a depthBuffer, or are you performing stencil shadowing for planar surfaces? If from a depthBuffer, you'll have to take into account a bias when sampling from the shadow map due to the limited precision of the depthBuffer. i.e. to little of a bias causes self shadowing, "acne", and to much of one can cause Peter Panning.

 

 

Marcus

Edited by markypooch

Share this post


Link to post
Share on other sites

Ok I think I have found the root cause.

 

When I create the texture from the lights POV it uses it fine, but when I rotate the camera I think the texture is also being rotated with everything else.

How would I fix this?

 

Tom

Share this post


Link to post
Share on other sites

Well, the answer is simple. Don't rotate your light viewMatrix with your player viewMatrix (Unless, of course, the position of the light can indeed rotate, and translate, or change directions). Somewhere in your update function, or else where, you must be updating both of them to some degree when receiving input.

 

At this point it may be a good idea to post realtive code to for these functions.

 

Marcus

Edited by markypooch

Share this post


Link to post
Share on other sites

I checked the functions and nothing changes the light rotation.

 

I have updated the post to show my code

Share this post


Link to post
Share on other sites

Are you updating the shadow map per frame? Or are you only creating/rendering to it at initialization time, and using the Shadow Map texture as input there on? If per frame, try just rendering to the shadow map once, and use the resulting texture from that point, and see if that resolves the issue.

Edited by markypooch

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!