Okay, finally fixed it. After altering some instructions a bit to tweak stuff, I discovered that it was the EXP instruction that was causing the problem, which I'll explain in minute. I got curious and replaced exp with sin and some variations below:

R0.y = sin( R0.x * 3.0 ) * 0.5;

That worked, but it was inaccurate. So I looked up the EXP instruction on the ARB_vertex_program documentation, and it said this:

Section 2.14.5.9, EXP: Exponential Base 2 (approximate)

The EXP instruction computes a rough approximation of 2 raised to thepower of the scalar operand. The approximation is returned in the "z"component of the result vector. A vertex program can also use the "x" and"y" components of the result vector to generate a more accurateapproximation by evaluatingresult.x * f(result.y),where f(x) is a user-defined function that approximates 2^x over thedomain [0.0, 1.0). The "w" component of the result vector is always 1.0.The exact behavior is specified in the following pseudo-code:float ScalarLoad(floatVec source){float operand;operand = source.c;if (negate) {operand = -operand;}return operand;}tmp = ScalarLoad(op0);result.x = 2^floor(tmp);result.y = tmp - floor(tmp);result.z = RoughApprox2ToX(tmp);result.w = 1.0;The approximation function is accurate to at least 10 bits:| RoughApprox2ToX(x) - 2^x | < 1.0 / 2^11, if 0.0 <= x < 1.0,and, in general,| RoughApprox2ToX(x) - 2^x | < (1.0 / 2^11) * (2^floor(x)).

It didn't hit me right away, but EXP is a multi-function instruction, and the original author was using the 2nd function. You select the function you want by selecting the destination field in your vector. So I changed that line to this:

R0.y = R0.x - floor( R0.x );

And now it works perfectly. Never would have guessed that was the problem. Now I can finally get on with life. Thanks for reading.

Shogun.