Jump to content

  • Log In with Google      Sign In   
  • Create Account

Sampling shadow-map inside an if-statement


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 maxest   Members   -  Reputation: 294

Like
0Likes
Like

Posted 10 December 2012 - 04:04 PM

I've read this article http://http.develope..._chapter17.html

Basically, in order to speed up shadow rendering we can check whether we are shading a pixel that faces away from the light, and in that case we can skip shadow computation (we know this pixel is in shadow).
So I implemented this. Here comes the code:
float NdotL = saturate(dot(-input.lightDirection, normal));
if (NdotL > 0.0)
{
diffuse *= NdotL;
input.shadowMapTexCoord.z += sunLightShadowMapBias;
#ifdef SOFT_SHADOWS
  float shadow = 0.0f;
  for (int i = 0; i < SOFT_SHADOWS_SAMPLES_NUM; i++)
  {
   float4 texCoord = input.shadowMapTexCoord;
   texCoord.xy += sunLightShadowsSoftness * poissonDiskTexCoords[i];
   shadow += tex2Dproj(shadowMap, texCoord).r;
  }
  shadow /= (float)SOFT_SHADOWS_SAMPLES_NUM;
#else
  float shadow = tex2Dproj(shadowMap, input.shadowMapTexCoord).r;
#endif

output.color += shadow * diffuse;
}

I'm using Cg and compile to D3D9 SM3.0 shaders, and OGL ARB shaders.

There is one problem however. Under D3D9 rendering is broken, giving me some random-colored flat-shaded surfaces. I would guess that hardware or the driver cannot handle texture lookups inside the if-statement but that could be a problem for a mipmapped texture. My shadow map has no mipmaps so I would expect texture lookups to work inside if-statements.
Moreover, on OpenGL everything works fine, yielding some slight performance boost when the if-statement is on.

Any ideas?

Sponsor:

#2 phil_t   Crossbones+   -  Reputation: 3928

Like
1Likes
Like

Posted 10 December 2012 - 08:55 PM

Sampling where a mipmap level has to be chosen (e.g. tex2D, tex2Dproj) can't be done from within a dynamic branch; so the branch will be flattened and execute for all pixels. You'll still get the same result (so I wouldn't think this is the reason for your "random-colored flat-shaded surfaces"), but you won't get the potential performance benefit.

But since your shadow map doesn't have mipmaps, you may as well use a sampling intrinsic where you explicitly specify the mipmap level (and specify 0), such as tex2Dlod (that's in HLSL - I'm not familiar with Cg, but I assume there is something similar). That works fine in an if statement. Also, in HLSL at least, you may need to add a [dynamic] attribute to the if statement to force it to be a dynamic branch (which I think will then generate a compile error if you use tex2D or tex2Dproj in the if clause).

#3 Hodgman   Moderators   -  Reputation: 30424

Like
0Likes
Like

Posted 11 December 2012 - 12:24 AM

Is output.color initialized to a default value before your if?

#4 maxest   Members   -  Reputation: 294

Like
0Likes
Like

Posted 15 March 2013 - 05:24 PM

Sorry guys for being mute so long on this subject but it completely went out of my mind.

 

@Hodgman: yes, it is.

 

@phil_t: Right. I was aware of most of the things you mentioned. I just fought that since my shadow map has only one mipmap there wouldn't be any problems with tex2Dproj. It's hard to tell for me now if using tex2Dlod could help cause, well, it's a hardware shadow map, so the only way I could get shadows is to call tex2Dproj and there is no variant of this function that would force a specific mipmap to load.

 

Anyway, I played a bit more with my code and found something interesting. Take a look at the code:

float NdotL = saturate(dot(-input.lightDirection, normal));

if (NdotL > 0.0)
{
    diffuse *= NdotL;

//    input.shadowMapTexCoord.z += sunLightShadowMapBias;
    float shadow = tex2Dproj(shadowMap, input.shadowMapTexCoord).r;

    output.color += shadow * diffuse;
}

And this one works! The reason is I commented out the line that shifts Z coordinates before sampling. Of course now I have some ugly acne but everything works as expected. I am aware of the fact that changing texcoords in the pixel shader allows hardware to speed up a little bit by using prefetching mechanism but I think that shouldn't affect the output of the pixel shader in such a severe way, right? Also, after all these months since I started this thread that output colors of pixels have changed from random flat-shaded colors to everything-in-snow-white.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS