Jump to content
  • Advertisement
Sign in to follow this  
bengaltgrs

DX9 Cube shadow maps

This topic is 2569 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'm attempting to implement cube mapped shadowing in DX9+HLSL, and I'm just about there, but I don't quite know how to finish the shader to actually display the shadows. The cube map (depth) is being generated correctly, which is evident when I return only the cube map texture in the pixel shader, so I know that part is working correctly. So my question is - how do I go about using the "shadowMap" variable in the pixel shader to properly display shadows?


float4x4 World;
float4x4 WorldViewProj;
float3 LightPos;

texture ColorTex;
texture CubeShadowTex;

#define SHADOW_EPSILON 0.00005f

sampler ColorSampler = sampler_state
{
Texture = (ColorTex);
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};

sampler CubeShadowSampler = sampler_state
{
Texture = (CubeShadowTex);
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};

struct CubeShadowMap_IN
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord0 : TEXCOORD0;
float3 Tangent : TANGENT;
float3 Binormal : BINORMAL;
};

struct CubeShadowMap_OUT
{
float4 position : POSITION0;
float3 lightDir : TEXCOORD0; // Vector from pixel to light
float2 texCoord : TEXCOORD1;
float depth : TEXCOORD2;
};

void VS(in CubeShadowMap_IN IN, out CubeShadowMap_OUT OUT)
{
//Transform the position from view space to homogeneous projection space
OUT.position = mul(IN.Position, WorldViewProj);

//Compute world space position
float4 WorldPos = mul(IN.Position, World);

//Compute light direction
OUT.lightDir = LightPos - WorldPos;

OUT.depth = length(OUT.lightDir);

// Pass texture coordinates through
OUT.texCoord = IN.TexCoord0;
}

float4 PS(in CubeShadowMap_OUT IN) : COLOR
{
//Pixel to light vector
IN.lightDir = normalize( IN.lightDir );

// Find color of pixel
float shadowMap = (texCUBE(CubeShadowSampler, IN.lightDir).r+SHADOW_EPSILON > IN.depth ? 0.0f : 1.0f);
float4 Color = tex2D(ColorSampler, IN.texCoord);

return Color * shadowMap;
}

Share this post


Link to post
Share on other sites
Advertisement
You check the distance of the current pixel and compare it to the distance data in the shadowmap. If the pixel distance (- some bias) is greater than the pixel data in the shadowmap then it gets shadowed (return darker color).


I went through a difficult learning curve with cubed shadow maps and point lights. In the end I chose a different lighting approach as cube maps eat up resources like crazy, regardless of your rendering technique.



Good luck!

Dj

Share this post


Link to post
Share on other sites
Thanks, yeah that's what I was attempting to do but I'm not sure how to get the proper depth value in the final rendering pass.

Share this post


Link to post
Share on other sites

Thanks, yeah that's what I was attempting to do but I'm not sure how to get the proper depth value in the final rendering pass.



Do you mean in the pixel shader or you have multiple passes for each light and you're wanting the shadowed color returned in the final pass?

Share this post


Link to post
Share on other sites
iI only have one pass per light, which is the shader above. So the issue I'm having is that the IN.depth value used in the pixel shader does not seem to be within the same range as the value returned from the cube shadow map. So in the pixel shader, if I return the shadowMap variable, then I see what looks like a correct shadow map. If I return the IN.depth value though, then I see all white.

Share this post


Link to post
Share on other sites

iI only have one pass per light, which is the shader above. So the issue I'm having is that the IN.depth value used in the pixel shader does not seem to be within the same range as the value returned from the cube shadow map. So in the pixel shader, if I return the shadowMap variable, then I see what looks like a correct shadow map. If I return the IN.depth value though, then I see all white.



When you're creating the cubed shadowmap what image fromat are you using?

Share this post


Link to post
Share on other sites
The cube map env map and cube map texture are being created like this:


D3DXCreateRenderToEnvMap(D3DDevice, CUBEMAP_RESOLUTION, 1, BackBufferSurfaceDesc.Format, TRUE, D3DFMT_D24X8, &RenderToEnvMap);
D3DXCreateCubeTexture(D3DDevice, CUBEMAP_RESOLUTION, 1, D3DUSAGE_RENDERTARGET, BackBufferSurfaceDesc.Format, D3DPOOL_DEFAULT, &CubeMapTexture);


Where BackBufferSurfaceDesc.Format is set to D3DFMT_X8R8G8B8.

Share this post


Link to post
Share on other sites
I used the R32F format and it was more percise but not all hardware support it.

Also, when I was sampling my cubeShadowMap I did the following (pseudo code):



lightDirection.xyz = lightPosition.xyz – positionWS;

float distance = length(lightDirection.xyz);

lightDirection.xyz = lightDirection.xyz / distance;

float smDepth = texCUBE(ShadowMapSampler, float4(-(lightDirection.xyz), 0.0f)).x;

if(distance > smDepth + 0.0001f)

{
//in shadow
}

Share this post


Link to post
Share on other sites
Interesting, I got it to kind of work.. I've attached what I have of the full project to this post if you have a moment to check it out.

Share this post


Link to post
Share on other sites

Interesting, I got it to kind of work.. I've attached what I have of the full project to this post if you have a moment to check it out.


Sorry Smit, on a box at work and cannot download. Post a screenshot of your results and I'll have a look.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!