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:
- You're not working in a pixel shader, so you can't use Sample
- You're trying to sample inside of a dynamic branch or dynamic loop construct, in which case gradients aren't available
- 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.
Edited by MJP, 29 December 2012 - 01:52 AM.