Load vs SampleGrad

Started by
1 comment, last by NiteLordz 11 years, 3 months ago

Can someone explain to me the difference between Load and SampleGrad, and when each should be used. I have used Load when dealing with the depth buffer before, and now i am looking at a sample app that uses SampleGrad also when dealing with a shadow map.

I am not sure which or when to use either.

Thanks in advance

Code makes the man
Advertisement

Load does not perform sampling, which means it doesn't do any address conversions or texture filtering. You simply say "give me the texel value at position (X, Y)", and you get the value of that single texel. It's often used in full-screen shaders where each output pixel directly corresponds to a single input pixel. For instance if you were writing a tone-mapping shader, in the pixel shader you might say "I'm writing out to pixel (345, 270) so give me the texel at (245, 270) from my input texture so that I can apply tone-mapping".

SampleGrad, like all of the other "Sample*" functions on the Texture object, will perform sampling. This means that...

  • You provide coordinates with [0, 1] floating-point UV coordinates as opposed to the integer used for Load
  • The UV coordinates will be wrapped, mirrored, or clamped based on the address mode specified for the SamplerState that you pass in
  • Texture filtering (including mipmap sampling and interpolation) will be applied according to the filtering mode specified for the SamplerState that you pass in

Now SampleGrad in particular is a variant of Sample that lets you pass in the gradients (partial derivatives of the U and V coordinates with respect to screen space X and Y). The normal Sample function will automatically calculate the gradients for you, which is done using the ddx/ddy partial derivative instructions that are available to pixel shaders. These gradients affect which mipmap(s) get used for sampling, as well as how many samples are used for anisotropic filtering. There are 3 reasons why you might not want to use the regular Sample function:

  1. You're not working in a pixel shader, so you can't use Sample
  2. You're trying to sample inside of a dynamic branch or dynamic loop construct, in which case gradients aren't available
  3. You're doing something special and you don't want to use the auto-calculated gradients

#2 is pretty common, so you might see code that calculates the gradients outside of a branch using ddx and ddy, and then passing them into SampleGrad. The code you saw was probably for some variant of Variance Shadow Mapping, since normal shadow maps are not filterable thus you wouldn't care about the gradients (if you don't have mipmaps or don't care about them, it's common to use SampleLevel and pass 0 as the mip level). I would guess that the code you saw was either doing it in a deferred rendering scenario (where you can't calculate the gradients during the lighting pass), or it was doing it inside of a dynamic branch.

Thanks, that explains in very well. I am looking at code right now to do cascaded shadow maps based on http://software.intel.com/en-us/vcsource/samples/shadow-explorer this sample. Right now, i am i inside the FilterSimple code, and it uses the SampleGrad, not inside the dynamic branch or anything, but i assume it's to keep the code complete.

Thanks again

Code makes the man

This topic is closed to new replies.

Advertisement