graph_shaders.py 6.1 KB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Aug  5 14:48:00 2019
Collection of shaders necessary to draw all elements of the graph.
@author: pavel
"""

from vispy import gloo, app, scene

#shaders for drawing nodes

vert = """
#version 120
// Uniforms
// ------------------------------------
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
uniform float u_antialias;
uniform float u_size;
uniform bool u_picking;

uniform vec3 u_graph_size;
// Attributes
// ------------------------------------
attribute vec3  a_position;
attribute vec4  a_fg_color;
attribute vec4  a_bg_color;
attribute float a_linewidth;
attribute float a_size;
attribute vec4  a_unique_id;
attribute float  a_selection;
// Varyings
// ------------------------------------
varying vec4 v_fg_color;
varying vec4 v_bg_color;
varying float v_size;
varying float v_linewidth;
varying float v_antialias;
varying vec4  v_unique_id;
varying float  v_selection;

varying float v_zoom_level;
void main (void) {
    v_size = a_size * u_size;
    v_linewidth = a_linewidth;
    v_antialias = u_antialias;
    v_fg_color  = a_fg_color;
    v_bg_color = a_bg_color;
    gl_Position = u_projection * u_view * u_model *
        vec4(a_position*u_size,1.0);
    gl_PointSize = v_size + 2*(v_linewidth + 1.5*v_antialias);
    v_zoom_level = u_view[0][0];
    v_unique_id = a_unique_id;
    v_selection = a_selection;
}
"""

frag = """
#version 120
// Constants
// ------------------------------------
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
uniform float u_antialias;
uniform float u_size;
uniform bool u_picking;

// Varyings
// ------------------------------------
varying vec4 v_fg_color;
varying vec4 v_bg_color;
varying float v_size;
varying float v_linewidth;
varying float v_antialias;
varying vec4 v_unique_id;

varying float v_zoom_level;
varying float v_selection;
// Functions
// ------------------------------------
float marker(vec2 P, float size);
float new_alpha(float zoom_level);
// Main
// ------------------------------------
void main()
{
 if(!u_picking)
 {
    float size = v_size + 2*(v_linewidth + 1.5*v_antialias);
    float t = v_linewidth/2.0-v_antialias;
    // The marker function needs to be linked with this shader
    float r = marker(gl_PointCoord, size);
    float d = abs(r) - t;
    if( r > (v_linewidth/3.0+v_antialias))
    {
        discard;
    }
    else if( d < 0.0 )
    {
       if(v_zoom_level < 0.0010)
       {
           float alpha = d/v_antialias;
           alpha = new_alpha(v_zoom_level);
            gl_FragColor = mix(vec4(1,1,1,0.9), v_bg_color, max(1.0-alpha, 0.3));
       }
       else
       {
           if(v_selection == 1.0)
               gl_FragColor = vec4(1.0, 0.0, 0.0, v_fg_color.a);
           else if(v_selection == 2.0)
               gl_FragColor = vec4(0.0, 1.0, 0.0, v_fg_color.a);
           else
               gl_FragColor = vec4(v_fg_color.rgb, v_bg_color.a);
       }
    }
    else
    {
        float alpha = d/v_antialias;
        if(v_zoom_level < 0.0010)
            alpha = new_alpha(v_zoom_level);
        else
            alpha = exp(-alpha*alpha);

        if (r > 0 && v_zoom_level >= 0.0010)
            gl_FragColor = vec4(v_fg_color.rgb, alpha*v_fg_color.a);
        else
            if(v_zoom_level < 0.0010)
                if(vec3(gl_Color.rgb) != vec3(v_bg_color.rgb))
                    gl_FragColor = mix(vec4(1,1,1,0.9), v_bg_color, max(1.0-alpha, 0.3));
                else
                    gl_FragColor = vec4(gl_Color.rgb, max(1.0-alpha, 0.1));
            else
                gl_FragColor = mix(v_bg_color, v_fg_color, alpha);
    }


 } else {
       float size = v_size +2*(v_linewidth + 1.5*v_antialias);
       float t = v_linewidth/2.0-v_antialias;
       // The marker function needs to be linked with this shader
       float r = marker(gl_PointCoord, size);
       float d = abs(r) - t;
       float alpha = d/v_antialias;
       if(v_zoom_level < 0.0010)
           alpha = new_alpha(v_zoom_level);
       else
           alpha = exp(-alpha*alpha);
       if(r > 0)
           gl_FragColor = v_unique_id;
       else
           gl_FragColor = v_unique_id;

    }
}

float marker(vec2 P, float size)
{
    float r = length((P.xy - vec2(0.5,0.5))*size);
    r -= v_size/2;
    return r;
}

float new_alpha(float zoom_level)
{
    float val = (zoom_level - 0.0010)/(0.00075-0.0010);
    if(val < 0)
    {
        val = 0;
    }
    return val;
}
"""

#Shaders for the lines between the nodes


vs = """
#version 120

// Uniforms
// ------------------------------------
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;

// Attributes
// ------------------------------------
attribute vec3 a_position;
attribute vec2 a_normal;
attribute vec4 a_fg_color;
attribute float a_linewidth;
//attribute vec4  a_unique_id;
//attribute vec4 l_color;

// Varyings
// ------------------------------------
varying vec4 v_fg_color;
varying float v_zoom_level;
varying vec2 v_normal;
varying float v_linewidth;

void main() {
    vec3 delta = vec3(a_normal*a_linewidth/(1-u_view[0][0]), 0);
    //vec4 pos = u_model * u_view * vec4(a_position, 1.0);
    //gl_Position = u_projection * (pos + vec4(delta, 1.0));
    gl_Position = u_model * u_view * u_projection * vec4(a_position+delta, 1.0);
    //gl_Position = u_projection * u_view * u_model *
    //    vec4(a_position, 1.0);
    v_zoom_level = u_view[0][0];
    v_fg_color = a_fg_color;
    v_normal = a_normal;
    v_linewidth = a_linewidth;

}
"""

fs = """
#version 120
// Varying
// ------------------------------------
varying vec4 v_fg_color;
varying float v_zoom_level;
varying vec2 v_normal;
varying float v_linewidth;

float new_alpha(float zoom_level);

void main()
{
      float l = length(v_normal);
      float feather = 0.5;
      float alpha = 1.0;
      if(l > v_linewidth/2.0+feather)
          discard;
      else
          alpha = 0.5;

      if(v_zoom_level < 0.0010)
            alpha = new_alpha(v_zoom_level);
      gl_FragColor = vec4(v_fg_color.rgb, alpha);
}

float new_alpha(float zoom_level)
{
    float val = (zoom_level-0.00075)/(0.0010-0.00075);
    if(val < 0.)
    {
        val = 0.;
    }
    return val;

}
"""