Saturday 8 September 2007

Invent ARB vertex trick

I've been experimenting with the vertex shader to go beyond the way one sinusoid function gave movement to the whole scene resulting in way too much ordered wind movement. It's not an easy task in ARB dialect. :-) Here is my solution (read the comments):

        if (doGrassMove) {
// creating 5 diffs to look random
diff = 0.059f * FastMath.sin(((passedTime / TIME_DIVIDER)
* windPower)) * windPower;
newDiffs[0] = diff;
diff = 0.059f * FastMath.sin((((passedTime + 500) / TIME_DIVIDER)
* windPower * (0.5f)))
* windPower;
newDiffs[1] = diff;
diff = 0.059f * FastMath.sin((((passedTime + 500) / TIME_DIVIDER)
* windPower * (0.6f)))
* windPower;
newDiffs[2] = diff;
diff = 0.059f * FastMath.sin((((passedTime + 1000) / TIME_DIVIDER)
* windPower * (0.8f)))
* windPower;
newDiffs[3] = diff;
diff = 0.059f * FastMath.sin((((passedTime + 2000) / TIME_DIVIDER)
* windPower * (0.7f)))
* windPower;
newDiffs[4] = diff;
diffs = newDiffs;

if (vertexShader) {
vp.setParameter(new float[]{diffs[0],diffs[0],0,0}, 0);
vp.setParameter(new float[]{diffs[1],diffs[1],0,0}, 1);
vp.setParameter(new float[]{diffs[2],diffs[2],0,0}, 2);
vp.setParameter(new float[]{diffs[3],diffs[3],0,0}, 3);
vp.setParameter(new float[]{diffs[4],diffs[4],0,0}, 4);
}


And the shader:


!!ARBvp1.0
PARAM mv[4] = { state.matrix.modelview };
PARAM mv2[4] = { state.matrix.projection };
TEMP pos,projpos;
TEMP a,b,c,div1,div2;
################################
# Apply modelview transformation
DP4 pos.x, mv[0], vertex.position;
DP4 pos.y, mv[1], vertex.position;
DP4 pos.z, mv[2], vertex.position;
DP4 pos.w, mv[3], vertex.position;
################################
# Add offset
TEMP f0,f1,f2,f3,f4;
TEMP t0,t1,t2,t3,t4;

# create different fraction parts
ADD f0, vertex.position, 0.0;
ADD f1, vertex.position, 0.1;
ADD f2, vertex.position, 0.2;
ADD f3, vertex.position, 0.3;
ADD f4, vertex.position, 0.4;

# get fraction and substract 0.5 to have
# negative values too
FRC f0, f0;
SUB f0, f0, 0.5;
FRC f1, f1;
SUB f1, f1, 0.5;
FRC f2, f2;
SUB f2, f2, 0.5;
FRC f3, f3;
SUB f3, f3, 0.5;
FRC f4, f4;
SUB f4, f4, 0.5;

# multiply different sinusoid external
# params by the texcoord y
# (highness of the quad) into t[] values
MUL t0, program.local[0], vertex.texcoord[0].yyyy;
MUL t1, program.local[1], vertex.texcoord[0].yyyy;
MUL t2, program.local[2], vertex.texcoord[0].yyyy;
MUL t3, program.local[3], vertex.texcoord[0].yyyy;
MUL t4, program.local[4], vertex.texcoord[0].yyyy;

# The trick: multiply with the different fractions,
# some of them may result in f[x] being 0, giving
# the randomness to the movement
# as one of the displacement will fall off
MUL f0, t0, f0;
MUL f1, t1, f1;
MUL f2, t2, f2;
MUL f3, t3, f3;
MUL f4, t4, f4;

# multiply with 2, bigger movements
MUL f0, f0, 2;
MUL f1, f1, 2;
MUL f2, f2, 2;
MUL f3, f3, 2;
MUL f4, f4, 2;

# add all the f[] offsets to position
ADD pos.xz, pos, f0;
ADD pos.xz, pos, f1;
ADD pos.xz, pos, f2;
ADD pos.xz, pos, f3;
ADD pos.xz, pos, f4;

################################
# Apply projection matrix
DP4 projpos.x, mv2[0], pos;
DP4 projpos.y, mv2[1], pos;
DP4 projpos.z, mv2[2], pos;
DP4 projpos.w, mv2[3], pos;
MOV result.position, projpos;
MOV result.texcoord[0], vertex.texcoord[0];
MOV result.color, vertex.color;
MOV result.fogcoord, vertex.fogcoord;

END

No comments:

Twitter