Q:

Random number hlsl

How do you generate a random number in HLSL?
I'm asking because I want to try gpu ray tracing.  You need to generate random directions in a pixel shader.  So I want randFloat(), where the result is a random number between -1 and +1.
Also, what is the deal with the hlsl noise instruction?  The docs say it was removed from HLSL 2.0 and up. Why?
I read about an approach where you fill a texture with random values, then have a texture coordinate in each vertex that has an index into that texture.  But that's per vertex, I need an instruction I can call in the pixel shader. Plus this approach requires "reseeding" the per-vertex texcoords if you want different values each frame, and that requires a vertex buffer update each frame (which can be expensive!)
With detail, how can you cheaply generate a random number on the GPU?

A:

Pseudo random numbers in a pixel shader aren't easy to obtain. A pseudo random number generator on the CPU will have some state which it both reads from and writes to, on every call to the function. You can't do that in a pixel shader.
Here's some options:

Use a compute shader instead of a pixel shader - they support read-write access to a buffer, so you can implement any standard PRNG.
Sample from one or more textures containing random data, based on a parameter like screen space position. You can also do some maths on the position before using it to look up into the texture, which should let you reuse the texture if the maths involves a random-per-draw-call shader constant.
Find some mathematical function of screen space position, that gives results that are 'random enough'.

A quick google search found this page with these functions:
float rand_1_05(in float2 uv)
{
    float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
    return abs(noise.x + noise.y) * 0.5;
}

float2 rand_2_10(in float2 uv) {
    float noiseX = (frac(sin(dot(uv, float2(12.9898,78.233) * 2.0)) * 43758.5453));
    float noiseY = sqrt(1 - noiseX * noiseX);
    return float2(noiseX, noiseY);
}

float2 rand_2_0004(in float2 uv)
{
    float noiseX = (frac(sin(dot(uv, float2(12.9898,78.233)      )) * 43758.5453));
    float noiseY = (frac(sin(dot(uv, float2(12.9898,78.233) * 2.0)) * 43758.5453));
    return float2(noiseX, noiseY) * 0.004;
}

