You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.9 KiB

vs.1.1
dcl_position v0
dcl_normal v3
// c0 = (0,0.5,1.0,2.0) (aka NumericConsts)
// c1 = frequencies
// c2 = phases
// c3 = amplitudes
// c4 = PiConsts = (1/(2PI), PI/2, PI, 2*PI) // NOTE THIS IS DIFFERENT
// because we don't need oonsqpi here but do want 1/2Pi.
// c5 = cosConsts = (1.0f, -1.0f/2.0f, 1.0f/ 24.0f, -1.0f/ 720.0f);
// c6 = ((cMax - cMin), cMin, 2ndLayerVOffset, 2ndLayerScale);
// c7 = overall color, including current opacity. Will
// probably only use the opacity, which we could stuff into
// the free slot of c6, but we're a wuss.
// First, "move" the position to oPos
mov r0, v0;
//mov r0.y, -r0.yyyy;
mov r0.w, c0.zzzz;
mov oPos, r0;
// Now the tricky part.
// The base layer defines the shape of the incoming wave
// The next layer has bubbles (noise) and moves in when the
// wave is moving in, moves out when wave is moving out.
// So calculate uvw for first layer, second uvw shares u val
// and v val is const
// The .x component of the normal
// tells us how much to shift this vert based on the
// cumulative cosine wave.
// Figure c = Sigma((cosine(v0.x * freq + phase) + 1) * amp);
// Note that range c must be [0..1]
// Also, c(-1) must equal c(1) so it will wrap.
// That implies freq = k * 2 * PI, where k is an integer.
// To keep c >= 0, we can add 1 to each term in the sigma BEFORE
// modulating by the amplitude.
// That puts our range at [0..2*sigma(amp)], so as long as
// sigma(amp) <= 0.5, we're fine.
// Get our input to cosine value (v0.x * freq + phase).
add r0, v0.xxxx, c0.zzzz;
mul r0, r0, c1;
add r0, r0, c2;
// Get it into range [-Pi..Pi]
// First divide out the 2PI
// add r0, r0, c4.zzzz; HACKOUT
mul r0, r0, c4.xxxx;
// Do an integer mod
expp r1.y, r0.xxxx
mov r1.x, r1.yyyy
expp r1.y, r0.zzzz
mov r1.z, r1.yyyy
expp r1.y, r0.wwww
mov r1.w, r1.yyyy
expp r1.y, r0.yyyy
//mov oD1, r1; // HACKTEST
//mov oD1.w, c0.zzzz; // HACKTEST
// Move back into PI space, w/ *= 2P, -= PI
mul r0, r1, c4.wwww;
sub r0, r0, c4.zzzz;
// Okay, compute cosine here.
// cos = 1 + r0^2 * kCos.y + r0^4 * kCos.Z + r0^6 * kCos.w
// Note: could pare off an instr by putting 1/kCos.w in kCos.x,
// then doing a mad to get r3=(1/kCos.w + r0^6), then mad that
// into the accum by kCos.w to get (1 + r0^6*kCos.x). But who cares.
mul r1, r0, r0; // r0^2
mul r2, r1, r1; // r0^4
mul r3, r1, r2; // r0^6
mov r4, c5.xxxx; // r4 = 1
mad r4, r1, c5.yyyy, r4; // r4 += r0^2 * kCos.y
mad r4, r2, c5.zzzz, r4; // r4 += r0^4 * kCos.z
mad r4, r3, c5.wwww, r4; // r4 += r0^6 * kCos.w
add r4, r4, c0.zzzz; // shift from [-1..1] to [0..2]
//mov r4, c0.xxxx; // HACKLAST
mul r4, r4, c3; // times amplitude
dp4 r5.y, r4, c0.zzzz; // r5.x = sigma((cos() + 1) * amp);
// V calculation, goes something like:
// For layers 0 and 2:
// V = { 1 + c6.z <= r5.y = 0 } * norm.x // norm.x == v3.x
// { 1 + 0 <= r5.y = 1 }
// For layer 1:
// V = (norm.x + c6.z) * c6.w // Scaled like U
//
// Another way to formulate that is
// baseV = cMin + sinAge * (cMax-cMin) where
// cMin = 2
// cMax = 1
// sinAge = color.a = c7.w
// delV = sigma(cos) = r5.y
// Then
// V0 = V2 = (baseV + delV) * v3.x
// V1 = (norm.x + baseV + delV) * c6.w
//
// If we're sure we want cMin = 2 and cMax = 1, then it simplifies to:
// baseV = 2 - sinAge = c0.w - c7.w
// delV = r5.y
// (baseV + delV) = c0.w - c7.w + r5.y
//
// If we want to stay general, then
// baseV = c6.x * c7.w + c6.y
// delV = -r5.y
// (baseV + delV) = constant + r5.y
//
// make r5.y = (baseV + delV)
add r5.y, c6.xxxx, r5.yyyy;
//mov oD1, r5.yyyy; // HACKLAST
//mov oD1.w, c0.zzzz; // HACKLAST
// U is input U (or v0.x * 0.5f + 0.5f)
mul r5.x, v0.x, c0.y;
add r5.x, r5.x, c0.y;
// Fill out wq.
mov r5.zw, c0.xz;
mul oT0, r5, v3.wxww;
// mov oD1, r5.yyyw; // HACKTEST
mul oT2, r5, v3.wxww;
// Second uv shares u, but v is norm.x + c6.x;
// Then we scale it.
// If we want the bubble texture to move with the
// wave front, we want the second UV calc (RESCALE1).
// But it looks better to have the bubbles moving
// slightly faster than the wave front. RESCALE0
// happens to do that, because we're scaling the
// texture by a factor of 2, but we should probably
// supply an independent scale of the motion vs. the
// scale of the texture.
// Let's move c6 to r6 for ease of use.
mov r6, c6;
// add r5.x, r5.x, c6.y;
// add r5.y, c6.xxxx, v3.xxxx; // RESCALE0
// mul r5.xy, r5, c6.wwww; // RESCALE0
add r5.x, r5.x, r6.y; // RESCALE1 // offset U
mov r5.y, v3.xx; // RESCALE1 // Init V to value stashed in normal.x
mul r5.xy, r5, r6.wwww; // RESCALE1 // scale them by single scale value
mad r5.y, r6.xx, r6.zz, r5.yy; // RESCALE1 // add in our scaled V offset (sinage * vScale)
mov oT1, r5;
//mov oT0, v7; // HACKTEST
//mov oT1, v7; // HACKTEST
//mov oT2, v7; // HACKTEST
// Just slam in the constant color (includes our current opacity).
mov oD0, c7;
//mov oD0, c0.zzzz; // HACKTEST