LYGIA Shader Library

shift (lygia/v1.1.6/color/dither/shift)

Vlachos 2016, "Advanced VR Rendering" http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf

Use:

<vec4|vec3|float> ditherShift(<vec4|vec3|float> value, <float> time)

Check it on Github


#ifdef DITHER_CHROMATIC
#define DITHER_SHIFT_CHROMATIC
#endif


#ifdef DITHER_ANIMATED
#define DITHER_SHIFT_ANIMATED
#endif

#ifndef DITHER_SHIFT
#define DITHER_SHIFT

float ditherShift(float b, float time) {
    //Bit-depth of display. Normally 8 but some LCD monitors are 7 or even 6-bit.   
    float dither_bit = 8.0; 

    vec2 st = gl_FragCoord.xy;
    #ifdef DITHER_SHIFT_ANIMATED 
    st += 1337.0*fract(time);
    #endif
    //Calculate grid position
    float grid_position = fract( dot( st - vec2(0.5,0.5) , vec2(1.0/16.0,10.0/36.0) + 0.25 ) );

    //Calculate how big the shift should be
    float dither_shift = (0.25) * (1.0 / (pow(2.0,dither_bit) - 1.0));

    //modify shift acording to grid position.
    dither_shift = mix(2.0 * dither_shift, -2.0 * dither_shift, grid_position); //shift acording to grid position.

    //shift the color by dither_shift
    return b + 0.5/255.0 + dither_shift; 
}

vec3 ditherShift(vec3 rgb, float time) {
    //Bit-depth of display. Normally 8 but some LCD monitors are 7 or even 6-bit.   
    float dither_bit = 8.0; 

    //Calculate grid position
    vec2 st = gl_FragCoord.xy;
    #ifdef DITHER_SHIFT_ANIMATED 
    st += 1337.0*fract(time);
    #endif
    float grid_position = fract( dot( st - vec2(0.5,0.5) , vec2(1.0/16.0,10.0/36.0) + 0.25 ) );

    //Calculate how big the shift should be
    float dither_shift = (0.25) * (1.0 / (pow(2.0,dither_bit) - 1.0));

    //Shift the individual colors differently, thus making it even harder to see the dithering pattern
    #ifdef DITHER_SHIFT_CHROMATIC
    vec3 dither_shift_RGB = vec3(dither_shift, -dither_shift, dither_shift);
    #else
    vec3 dither_shift_RGB = vec3(dither_shift);
    #endif

    //modify shift acording to grid position.
    dither_shift_RGB = mix(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position.

    //shift the color by dither_shift
    return rgb + 0.5/255.0 + dither_shift_RGB; 
}

vec4 ditherShift(vec4 rgba, float time) {
    return vec4(ditherShift(rgba.rgb, time), rgba.a);
}

#endif

Use:

<float4|float3|float> ditherShift(<float4|float3|float> value, <float> time)

Check it on Github


#ifdef DITHER_CHROMATIC
#define DITHER_SHIFT_CHROMATIC
#endif


#ifdef DITHER_ANIMATED
#define DITHER_SHIFT_ANIMATED
#endif

#ifndef DITHER_SHIFT
#define DITHER_SHIFT

float ditherShift(float b, float2 fragcoord, float time) {
    //Bit-depth of display. Normally 8 but some LCD monitors are 7 or even 6-bit.   
    float dither_bit = 8.0; 

    #ifdef DITHER_SHIFT_ANIMATED 
    fragcoord += 1337.0*frac(time);
    #endif
    //Calculate grid position
    float grid_position = frac( dot( fragcoord - float2(0.5,0.5) , float2(1.0/16.0,10.0/36.0) + 0.25 ) );

    //Calculate how big the shift should be
    float dither_shift = (0.25) * (1.0 / (pow(2.0,dither_bit) - 1.0));

    //modify shift acording to grid position.
    dither_shift = lerp(2.0 * dither_shift, -2.0 * dither_shift, grid_position); //shift acording to grid position.

    //shift the color by dither_shift
    return b + 0.5/255.0 + dither_shift; 
}

float3 ditherShift(float3 rgb, float2 fragcoord, float time) {
    //Bit-depth of display. Normally 8 but some LCD monitors are 7 or even 6-bit.   
    float dither_bit = 8.0; 

    //Calculate grid position
    #ifdef DITHER_SHIFT_ANIMATED 
    fragcoord += 1337.0*frac(time);
    #endif
    float grid_position = frac( dot( fragcoord - float2(0.5, 0.5) , float2(1.0/16.0,10.0/36.0) + 0.25 ) );

    //Calculate how big the shift should be
    float dither_shift = (0.25) * (1.0 / (pow(2.0,dither_bit) - 1.0));

    //Shift the individual colors differently, thus making it even harder to see the dithering pattern
    #ifdef DITHER_SHIFT_CHROMATIC
    float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift);
    #else
    float3 dither_shift_RGB = float3(dither_shift, dither_shift, dither_shift);
    #endif

    //modify shift acording to grid position.
    dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position.

    //shift the color by dither_shift
    return rgb + 0.5/255.0 + dither_shift_RGB; 
}

float4 ditherShift(float4 rgba, float2 fragcoord, float time) {
    return float4(ditherShift(rgba.rgb, fragcoord, time), rgba.a);
}

#endif

Examples

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository