Why does writing this same thing in two different ways give different results in glsl?

36 Views Asked by At

So I'm learning how to code value noise in glsl and I get this curious problem. I was trying to figure out why I was getting discontinuities in the image no fix image Here is the code for the value noise function

float valueNoise(vec2 v, float n){
    v*=n;
    vec2 bl = floor(v);
    vec2 fr = fract(v);
    vec2 br = vec2(bl.x+1.,bl.y);
    vec2 tl = vec2(bl.x,bl.y+1.);
    vec2 tr = vec2(bl.x+1.,bl.y+1.);
    float top = mix(random2D(tl),random2D(tr), fr.x);
    float bottom = mix(random2D(bl),random2D(br), fr.x);
    return mix(bottom, top, fr.y);
}

So I decided to change this line

vec2 br = vec2(bl.x+1.,bl.y);

to this line

vec2 br = bl + vec2(1.,0.);

so that now the function looks like this

float valueNoise(vec2 v, float n){
    v*=n;
    vec2 bl = floor(v);
    vec2 fr = fract(v);
    vec2 br = bl + vec2(1.,0.);
    vec2 tl = vec2(bl.x,bl.y+1.);
    vec2 tr = vec2(bl.x+1.,bl.y+1.);
    float top = mix(random2D(tl),random2D(tr), fr.x);
    float bottom = mix(random2D(bl),random2D(br), fr.x);
    return mix(bottom, top, fr.y);
}

and not only did this change the image (which it shouldn't since these two lines should be equivalent). But it also fixed the discontinuity problem! Here is how it looks after the change: after fix image Also I'm surprised by the fact that It was fixed by me only changing br (bottom right) without even fixing all the others. For reference, here is the rest of the code:

// Author:
// Title:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
float random2D(vec2 v){
    return fract(954356.2345*sin(dot(vec2(1.13567,5.245),v)));
}
float random(float k){
    return fract(9125823.3256*sin(4656.4568*k));
}
float valueNoise(vec2 v, float n){
    v*=n;
    vec2 bl = floor(v);
    vec2 fr = fract(v);
    vec2 br = bl + vec2(1.,0.);
    vec2 tl = vec2(bl.x, bl.y+1.);
    vec2 tr = bl + vec2(1.);
    float top = mix(random2D(tl),random2D(tr), fr.x);
    float bottom = mix(random2D(bl),random2D(br), fr.x);
    return mix(bottom, top, fr.y);
}
void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    //st.x *= u_resolution.x/u_resolution.y;
    
    st = st*2.-vec2(1.);
    

    vec3 color = vec3(valueNoise(st, 7.));
    //color = vec3(random2D(st));

    gl_FragColor = vec4(color,1.0);
}

Also, I tried changing all the others (tl, tr) in case they too might have been problematic but that doesn't change anything, only br.

So, to sum up, my question is: why are vec2 br = bl + vec2(1.,0.); and vec2 br = vec2(bl.x+1.,bl.y); not equivalent and, in fact, the second one doesn't work correctly?

0

There are 0 best solutions below