I have this correctly-working OpenGL shader producing Perlin noise:
float left = lerp(fade(v), downleft, topleft);
float right = lerp(fade(v), downright, topright);
float result = lerp(fade(u), left, right);
Then I tried plugging the definitions of right and left into result:
float result = lerp(fade(u),
lerp(fade(v), downleft, topleft),
lerp(fade(v), downright, topright));
Surprisingly, this behaves completely differently, giving visible edges in my Perlin noise. Below are both results:
My whole 30-line shader is here.
What is the difference between those?

leftin twice or something? \$\endgroup\$