Archive for the GPU Random Number Category

One more video (432*432 number of robots,zombies,eat-them-freaks–whatever)

Posted in GPU Random Number, c++, gpu, programming, project zombie with tags on April 9, 2009 by bey0ndy0nder

Next version will look very different and hopefully with better crowd behavior! I want flying things, destructible environments, fire effects and atmospheric effects, buildings…and definitely some sort of behavior.

BTW, sound clip IS FREE and was taken off some site advertising Resident Evil Apocalypse–this is off google search on FREE Resident Evil music. Also, I’m not making any political or general statement with choice of sound clip.

PLUS, WTF IS WRONG with the quality man??? IT DOES HOWEVER is giving the scene a darker feel to it.

OH noes! Frapping Zombies!!!

Posted in GPU Noise, GPU Random Number, c++, gpu, programming, project zombie with tags on April 8, 2009 by bey0ndy0nder

Finally fixed the issues.

I’m going to spend the next few days going back and document the hell out of everything. Maybe do some resource refactor… then again, maybe not, I want to start working on Spherical harmonics!

BTW, what do I have to do to get some better vid qualities. I encoded it at 3000kb/s… hmmm, maybe I have to increase duration in order for youtube HD to kick-in?

It don’t matter. The video sucks any

OpenGL 3.0 and GLSL 1.3 (Is it 1.3? Forgot.)

Posted in GPU Noise, GPU Random Number, programming, project zombie, thoughts on April 4, 2009 by bey0ndy0nder

I’m trying to run my compiled and linked Project Zombie executable. And it turns out, I have some problems (it never is easy, huh?).

The problems involve Nvidia (I think) specific GLSL 32bit integer syntax and calls. But hurray and thank the powers-that-be for OpenGL 3.0! OGL 3.0 — and GLSL 1.3 — has all the native support for integers. So, the only thing left to do is fix all the little syntactical and semantically incompatibilities between the Nvidia stuff and the OGL 3.0 stuff; since both ATI and Nvidia released driver support for OGL 3.0 — give it up for mofo’kin standards, bitches!

So, I should have it up and running in no time. (Mostly, the problems involve wrapping “uint” around the “trunc” function.)

With all that, now I have to actually think about where I want the project to head to next. I think I’m going to work on gFx glitz next, just to jAzz it up a bit, for the ladies. No, actually I want to work on some simple procedural building stuff ON TOP of some Spherical Harmonics lighting — for outdoor lighting with analytic sky models.

As for why some developers are hating on OGL 3.0 and moving their development (well, hobby, in my case) to DirectX 3.0. I thought about it hard, I even contemplated moving to DirectX 10 (it is still not off the table yet — I mean hey, I’m using Ogre, so all that is abstracted anyway; but it may still involve lots of hoop jumping). But the POINT is I don’t care too much about GfX jazz right now… sure I will have some stuff, so it looks decent, but I want to explore computation-intensive stuff that adds values to something OTHER THAN graphics. Like global ceullar-automata-based dynamics, or some other such esoteric s*** that main-stream developers don’t give a rat’s ass about. Maybe it is not esoteric, more like, I don’t really know what the f*** I’m doing, but I’m imagining things, in my head that I think is “cool,” so I want to explore it further; yet, I really don’t have everything clearly mapped-out. Hmmm…

It’s ALIVE…(and some ramblings on imposters)

Posted in GPU Random Number, programming, project zombie, source code with tags on October 10, 2008 by bey0ndy0nder

I finished preliminary implementation of GPU based zombie movement. Right now it’s very simple, but I’m working on it. it’s coming together nicely. My next step is to finish the Imposter renderer. After that, I will on interaction between the world and the zombies. The game-play would suck if all the zombies just wandered around like … well.. zombie. I will blog about game-play ideas in an upcoming post.

Here is the ping pong source code to update the zombies (onUpdate function):

The Code

Notice that I’m using a naked pointer. I know it’s bad, but my idea is that this is the controller, and thus is not responsible for the state (the model). I think I should change it from pointer to reference to make that “borrowing” notion more clear. I think it should be a priority that I change my habit to use references more often.

And here are the two shaders:

positional update

directional update

Finished Imposter implementation:

The imposter renderer is not yet finished. All the imposter “views” are facing the camera; it does not correspond to the actual direction of the zombie. So to get the proper “view” of the imposter, we need to take into account the eye direction with respect to direction of the zombie.

Our imposters are stored in a single texture, and mapped according to two keys that is based on sphereical coordinate parameter of phi and theta, corresponding to the viewing direction. Thus, to properly calculate which imposter “view” texture to render we must map the current view direction into this singlular imposter storage texture. Therefore, the proper solution is to compute phi and theta from the current viewing vector.

We know that (let’s assume r = 1):

phi = arccos(z)

theta = atan2(y/x). (remembering to add 2pi for negative values).

But we know that actan2 is undefined when y = 0 and x = 0. So we need to carefully examine this case: When this happens, we are looking down at the object in question. But we can still derive theta, by looking at the camera’s orthonormal basis. Thus, when y=0 and x=0, we use the camera’s local axes. However, we need to transform the camera’s local axes into the object space. This can be done by noting the following:

For our purposes, we only require one degree of freedom, namely yaw, for the zombie. So the zombie’s directional vector will always be in the XY plane. So again, using atan2, we can compute it’s angle from the object’s direction in object space. So, we can then construct a rotation matrix, or quaternion, or whatever, which corresponds to the transformation of the object from object space into world space. Thus, the inverse of this transformation will transform the camera’s orthonormal basis in world space into object space. From here, we can then use it to compute theta by following the scheme noted above.

Zombie “smooth wandering.” (randomly)

Posted in GPU Noise, GPU Random Number, programming, project zombie, thoughts with tags , , on October 7, 2008 by bey0ndy0nder

Right, I mentioned in an earlier post that I need my Zombies to wander randomly. However, if I simply randomly change the orientation the behavior would be similar to random walk. I.E. changing of orientation would not be “smooth.” So we need some sort of interpolation. First, I only need one degree of freedom for this sort of orientation, e.g. yaw. Secondly, I don’t need much precision, since the plan is to smoothly interpolate between orientations. So, some preliminary brainstorm suggests that I can pack a 2d vector (on the xy plane) into a 32bit float. That leaves me with 3 free floats left, which I can use to store interpolation offset. This leaves me with the question of “uniform smoothness” during orientation interpolation. I do not want to use quaternions since I only require a single degree of freedom. Perhaps I can store a single float “theta factor,” and interpolate this theta (i.e. X = cos(t)i + sin(t)j).

Edited:
Maybe I need to give some more thoughts into this. Smoothly interpolating orientation is fine, but we also need to think about the rate of this rotation. THis probably will be a randomized factor also. I don’t EVERYTHING to have smooth rotation, some need to arbitrarily change directions. Yeah, I think randomness will be fine. Just have to have some sort interpolation tho, so you won’t have TOO abrupt of a change.

MD5GPU reloaded (and debugged):

Posted in GPU Noise, GPU Random Number, glsl, gpu, mathematics, programming, project zombie, source code, thoughts with tags , , , , on October 5, 2008 by bey0ndy0nder

It’s working now. I haven’t tested it with DIEHARDER yet, I may do it later, when I have time. But if it looks like white noise, walks likes whitenoise…

BTW, the author’s (of the paper) optimization works fine. Realy, think about it, why wouldn’t it work? It’s still rotating, that’s all matters really.

I’m going to start working on the agent simulation part of PZ.

#extension GL_EXT_gpu_shader4 : enable
//This function initializes the 512bit data according to the MD5 spec.
//Such that, the first 128 bit is the input;
//we also xor these 128 bits with the key, which can act like a seed value.
//And the rest up of the 12 32bit data blocks are filled
//according to the md5 spec, in order to pad our data to 512 bits.
//block 0-3: input xor with key
//block 4: 0x80000000. This correponds to append 1 bit to block 0-4.
//block 5-13: 0. This corresponds to appending zeros up to 448 bit.
//block 14-15: 0x0000000000000080. This correspond to the bit length of the input (128 bit), as a 64bit
//litten endian.
void setupInput(in uvec4 input, in unsigned int key, inout unsigned int data[16])
{
	data[0] = input.x^key; data[1] = input.y^key; data[2] = input.z^key; data[3] = input.w^key; //xor base with key
	data[4] = 0x80000000u;
	data[5] = 0u; data[6] = 0u; data[7] = 0u; data[8] = 0u;
	data[9]=0u; data[10]=0u; data[11]=0u; data[12]=0u; data[13]=0u;
	data[14] = 0x00000000u; data[15]=0x00000080u;
}
//initialize to the 4 hexes.
uvec4 initDigest()
{
	return uvec4(0x01234567u,0x89ABCDEFu,0xFEDCBA98u,0x76543210u);
}
//F compression functions
//(b & c) | ((not b) & d)
unsigned int F0_15(in uvec3 tD)
{
	return (tD.x & tD.y) | ((~tD.x) & tD.z);
}
//(d & b) | ((not d) & c)
unsigned int F16_31(in uvec3 tD)
{
	return (tD.z & tD.x) | ((~tD.z) & tD.y);
}
//b ^ c ^ d
unsigned int F32_47(in uvec3 tD)
{
	return tD.x ^ tD.y ^ tD.z;
}
//c ^ (b | (~d))
unsigned int F48_63(in uvec3 tD)
{
	return tD.y ^ (tD.x | (~tD.z));
}

//return input/(2^32) //2^32 - 1.0 + 1.0
vec4 convertToR0_R1(in uvec4 input)
{

	return output;
}

uvec4 whiteNoise(in uvec4 input,in unsigned int key)
{
	unsigned int data[16];
	setupInput(input,key,data);
	uvec4 rot0_15 = uvec4(7u,12u,17u,22u);
	uvec4 rot16_31 = uvec4(5u,9u,14u,20u);
	uvec4 rot32_47 = uvec4(4u,11u,16u,23u);
	uvec4 rot48_63 = uvec4(6u,10u,15u,21u);

	uvec4 digest = initDigest();
	uvec4 tD;
	uvec4 fTmp;
	unsigned int i = 0u;
	unsigned int idx;
	unsigned int r;
	unsigned int trig; const unsigned int MAXFT = 4294967295; //2^32-1
	//What follows is the unrolled loop from 0 through 63
	//0
	tD = digest;
	unsigned int temp;
	for(;i<16u;i++)
	{
		fTmp = F0_15(tD.yzw);
		idx = i;
		r = rot0_15.x;
		rot0_15 = rot0_15.yzwx;
		trig = truncate(abs(sin(float(i+1)))*float(MAXFT));
		tD.x = tD.y + ((tD.x+fTmp+data[int(idx)]+trig) << r);
		tD = tD.yzwx;

		digest +=tD;
	}
	for(;i<32u;i++)
	{
		fTmp = F16_31(tD.yzw);
		idx = (5u*i + 1u) % 16u;
		r = rot16_31.x;
		rot16_31 = rot16_31.yzwx;
		trig = truncate(abs(sin(float(i+1)))*float(MAXFT));
		tD.x = tD.y + ((tD.x+fTmp+data[int(idx)]+trig) << r);
		tD = tD.yzwx;
		digest +=tD;
	}
	for(;i<48u;i++)
	{
		fTmp = F32_47(tD.yzw);
		idx = (3u*i + 5u) % 16u;
		r = rot32_47.x;
		rot32_47 = rot32_47.yzwx;
		trig = truncate(abs(sin(float(i+1)))*float(MAXFT));
		tD.x = tD.y + ((tD.x+fTmp+data[int(idx)]+trig) << r);
		tD = tD.yzwx;
		digest +=tD;
	}
	for(;i<64u;i++)
	{
		fTmp = F48_63(tD.yzw);
		idx = (7u*i) % 16u;
		r = rot48_63.x;
		rot48_63 = rot48_63.yzwx;
		trig = truncate(abs(sin(float(i+1)))*float(MAXFT));
		tD.x = tD.y + ((tD.x+fTmp+data[int(idx)]+trig) << r);
		tD = tD.yzwx;
		digest +=tD;
	}

	return digest;
}