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:

enter image description here

My whole 30-line shader is here.

What is the difference between those?

  • 1
    \$\begingroup\$ Some trivia notes -- your lerp() is equivalent to the built-in function mix(). And, it may be handy to put your shader into ShaderToy, as a convenient way for others to easily run/debug it. (That all said, I'm so far mystified why the substitution would do what it seems to be doing.) \$\endgroup\$ – david van brink Oct 23 '15 at 18:47
  • \$\begingroup\$ I bet that you're taking coordinates from each render in one of them and screen in the other. \$\endgroup\$ – Lolums Nov 1 '15 at 10:43
  • \$\begingroup\$ @Lolums 34 can you rephrase? I did not quite get you. \$\endgroup\$ – hungry91 Nov 1 '15 at 11:20
  • 1
    \$\begingroup\$ @hungry91 ignore that comment, it's invalid. I'll try to answer the question later though when I get some time :) \$\endgroup\$ – Lolums Nov 1 '15 at 14:53
  • \$\begingroup\$ I'm unable to recreate this. Are you sure you didn't accidentally plug left in twice or something? \$\endgroup\$ – Yousef Amar Nov 24 '15 at 22:00

It seems like the processing system is loosing floating point precision because you're not declaring memory for the variable. Normally this isn't a problem, however it seems that your lerp function requires a good bit of precision. Imagine this: computers cannot know irrational numbers. So if X is the square root of 5, and Y is the square root of 3. Saying X + Y is different than sqrt(5) + sqrt(3)

This is because on the lower level the data in the first operation goes

data > memory > cpu > memory

And in the second operation it's more like

Data > cpu > memory

While faster, this operation results in precision loss, especially in 32 bit systems.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.