Sign in to follow this  
monkeyboi

Randomness In shader

Recommended Posts

monkeyboi    188
I am trying to get some random number in shader
please have a look if this could work

In shader

float GetRandomFloat(float Offset, float a, float b)
{
float temp = 0.0;

temp = Randomness%1000;
temp = (temp+Offset);
temp = temp/30.0;
// Get random float in [0, 1] interval.
float f = (temp%101) * 0.01f;
float c = b-a;
f = f*c+a;
return (f);

}



Here Randomness is a float value generated every frame using rand() and offset is a distinctive member that is different among each point
so I expect I could get a random number lacated in the interval from a to b for example GetRandomFloat(offset,-5,5) should return a value less than 5 greater than -5
what do you think?

Share this post


Link to post
Share on other sites
Gavin Williams    985
Hi monkeyboi,

I tested your GetRandomFloat function across the range 0.0 to 99.0 using bounds
of 0 and 1. Here's the code i used to run that test :


// change randomness once for frame
fnTester.ChangeRandomness();

float[] output = new float[100];

for (int offset = 0; offset < 100; offset++ )
{
output[offset] = fnTester.GetRandomFloat((float)offset, 0, 1);
Debug.fileText += (output[offset]) + "\n";
}





The output looked like this :

0.0002490178 1st output
0.0005823511
0.0009156844
0.001249018
0.001582351
0.001915684
0.002249018
0.002582351
0.002915684
0.003249018

...

0.03024902
0.03058235
0.03091568
0.03124902
0.03158235
0.03191569
0.03224902
0.03258235
0.03291569
0.03324902 100th output

So as you can see it doesn't produce random output but rather output that is linear. It also doesn't generate numbers fully across the bounded range, 0 to 1 using arbitrary but unique values, in this case 0.0 to 99.0. The values produces only range from 0.0002490178 to 0.03324902.

So your function would not serve well as a random number generator.

You haven't said what you need it for, but why not pre-render a texture with random colors, by rendering into an array using Random class (xna example) and then copying that array to your texture. I've used that method for a cloud-fractal animated sky-box

alt="Randomness on textures" />
see http://yfrog.com/mgreflectshaderscreenj

[Edited by - Gavin Williams on December 5, 2010 9:09:50 AM]

Share this post


Link to post
Share on other sites
monkeyboi    188
Hi Gavin

Thanks for your replying
That is my bad forgot to say that offset value is a random number as well
when I create the vertices I use texture coordinate to store some random numbers as offset. so right now I don't think your test is convinced sorry about that.

But as you said I don't think I could use this method get randomness neither. Because in my debugging, I find the random number is either all positive or negtive I don't know why here is my debug pixel shader

float4 PSUpdate(float2 texcoord: TEXCOORD1,float2 offset: TEXCOORD2): COLOR0{
float4 tempCol = tex2D(TexSampler,texcoord);
tempCol = tempCol*2;
tempCol.x = tempCol.x + GetRandomFloat(offset.x,-5,5);
return tempCol;
}


and the value GetRandomFloat() return is
2.49 1st frame
4.466
4.747
3.183
4.91
2.25

You can see the number is random but all of them is positive

And using texture to generate randomness is a good idea but I was thinking if I have to generate a pair of random coordinates for the texture why not just generate a random number directly.

Share this post


Link to post
Share on other sites
Gavin Williams    985
monkeyboi,


After a couple of silly attempts I came up with the following code using a number sequence generator as found at The University of Utah Website. Notice that I'm passing the previous value from GetRandomFloat back into it, which creates a problem for me because I can't pass values between vertices.


public float GetRandomFloat2(float offset, float lower, float upper, float prevValue)
{
// set characteristics of number sequence generator
int P1 = 263;
int P2 = 71;

// normalize prevValue
float height = upper - lower;
prevValue = (prevValue - lower) / height;

// compute next term from random number sequence generator
float normalizedRndNumber = ((prevValue * P1 + P2) % 1) % 1;

// transform normalizedRndNumber to the range { lower <= y= < upper }
float output = lower + normalizedRndNumber * height;

// return ranged value
return output;
}



I tested this with the Randomness value being timer based and the offset seed based (Random rnd = new Random(1028);)

Oh, and here's my updated testing code which I think better reflects your offset values :


// initialize vertex texCoords
Random rnd = new Random(1028);
float[] offset = new float[100];
float[] output = new float[100];
for (int texInd = 0; texInd < 100; texInd++ )
{
offset[texInd] = (float)(rnd.NextDouble());
}

// change randomness once for frame
fnTester.ChangeRandomness();

// generate output values (which we hope appear randomized over time)
float prevValue = fnTester.Randomness; // seed each frame
for (int texInd = 0; texInd < 100; texInd++)
{
prevValue = output[texInd] = fnTester.GetRandomFloat2(offset[texInd], -5, 5,prevValue);
}

// Send output values to text file
for (int texInd = 0; texInd < 100; texInd++)
{
Debug.fileText += (output[texInd]) + "\n";
}



And here's the first 10 outputs for the first frame:

3.53244
-0.9682626
-4.653051
-3.752514
3.088844
2.366082
2.279585
-0.469144
-3.384869
-0.2204555

So, this doesn't solve the problem but I hope I at least understand the problem now :)

Share this post


Link to post
Share on other sites
monkeyboi    188
Hi Gavin

I gave a glance at the link thank you very much

But I still dont understand what is wrong in my codes

In your code, you use prevalue as a random number then follow the theory found at the link finally clamp the value in an area. Is this true?

If it is true, I think that is quite similar with mine.

Do you know what is wrong in my code? thanks again

Share this post


Link to post
Share on other sites
monkeyboi    188
Quote:
Original post by pcmaster
What about a texture? Generate many random numbers/vectors on CPU/whatever and upload them to a texture and just use that?


Yeah I know as I said tho I use texture I need to generate a random texture coordinate I think so why not just generate a random number directly?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this