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
167 lines
4.9 KiB
4 years ago
|
|
||
|
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
|