shade.fs 9.04 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/**************************************************************************************/
/*                                                                                    */
/*  Copyright (c) 2005-2016, Michele Bosi.                                            */
/*  All rights reserved.                                                              */
/*                                                                                    */
/*  This file is part of Visualization Library                                        */
/*  http://visualizationlibrary.org                                                   */
/*                                                                                    */
/*  Released under the OSI approved Simplified BSD License                            */
/*  http://www.opensource.org/licenses/bsd-license.php                                */
/*                                                                                    */
/**************************************************************************************/
13

14
#version 150 compatibility
15

16
#pragma VL include /vivid/glsl/uniforms.glsl
17

18 19 20 21 22
in vec4 OP; // object-space vertex
in vec4 WP; // world-space vertex
in vec4 CP; // camera-space vertex
in vec3 N;
in vec4 Color;
23 24 25

// Utils

Michele Bosi's avatar
Michele Bosi committed
26
vec3 AdjustSaturation( vec3 rgb, float adjustment )
27
{
Michele Bosi's avatar
Michele Bosi committed
28 29 30
    const vec3 W = vec3( 0.2125, 0.7154, 0.0721 );
    vec3 intensity = vec3( dot( rgb, W ) );
    return mix( intensity, rgb, adjustment );
31 32 33 34 35 36
}

// Stages

vec4 LightingStage()
{
Michele Bosi's avatar
Michele Bosi committed
37
  vec4 color;
Michele Bosi's avatar
Michele Bosi committed
38 39 40 41 42 43
  if ( vl_Vivid.outline3DRendering || ! vl_Vivid.enableLighting )
  {
    color = Color;
  }
  else
  {
44 45 46 47
    vec3 l = normalize( gl_LightSource[0].position.xyz - CP.xyz );
    vec3 e = normalize( vec3( 0, 0, 0 ) - CP.xyz ); // vec3( 0.0, 0.0 ,1.0 ) for GL_LIGHT_MODEL_LOCAL_VIEWER = FALSE
    vec3 n = normalize( N );
    vec3 H = normalize( l + e );
48

49 50 51 52 53 54 55
    // compute diffuse equation
    float NdotL = dot( n, l );
    // dual side lighting
    if ( NdotL < 0 ) {
      NdotL = abs( NdotL );
      n = n * -1;
    }
56

57 58
    vec3 diffuse = gl_FrontMaterial.diffuse.rgb * gl_LightSource[0].diffuse.rgb;
    diffuse = diffuse * vec3( max( 0.0, NdotL ) );
59

60 61 62 63 64
    float NdotH = max( 0.0, dot( n, H ) );
    vec3 specular = vec3( 0.0 );
    if ( NdotL > 0.0 ) {
      specular = gl_FrontMaterial.specular.rgb * gl_LightSource[0].specular.rgb * pow( NdotH, gl_FrontMaterial.shininess );
    }
65

66 67
    vec3 ambient  = gl_FrontMaterial.ambient.rgb * gl_LightSource[0].ambient.rgb + gl_FrontMaterial.ambient.rgb * gl_LightModel.ambient.rgb;
    vec3 emission = gl_FrontMaterial.emission.rgb;
68

Michele Bosi's avatar
Michele Bosi committed
69 70
    color.rgb = ambient + emission + diffuse + specular;
    color.a = gl_FrontMaterial.diffuse.a;
71
  }
Michele Bosi's avatar
Michele Bosi committed
72

Michele Bosi's avatar
Michele Bosi committed
73
  if ( vl_Vivid.enablePointSprite ) {
74 75 76 77
    if ( vl_Vivid.textureDimension == 2 ) {
      color = color * texture2D( vl_UserTexture2D, gl_PointCoord.st );
    }

78 79 80 81
    // More aggressive pixel discard for point sprites
    if ( color.a < 0.004 ) {
      discard;
    }
Michele Bosi's avatar
Michele Bosi committed
82
  } else
Michele Bosi's avatar
Michele Bosi committed
83
  if ( vl_Vivid.enableTextureMapping ) {
84 85 86 87 88 89 90 91 92 93
    if ( vl_Vivid.textureDimension == 1 ) {
      color = color * texture1D( vl_UserTexture1D, gl_TexCoord[0].s );
    } else
    if ( vl_Vivid.textureDimension == 2 ) {
      color = color * texture2D( vl_UserTexture2D, gl_TexCoord[0].st );
    } else
    if ( vl_Vivid.textureDimension == 3 ) {
      color = color * texture3D( vl_UserTexture3D, gl_TexCoord[0].str );
    }

94
  }
Michele Bosi's avatar
Michele Bosi committed
95 96

  return color;
97 98
}

Michele Bosi's avatar
Michele Bosi committed
99
vec4 ClippingStage( vec4 color )
100 101
{
    // return color;
Michele Bosi's avatar
Michele Bosi committed
102
    for( int i = 0; i < VL_SMART_CLIP_SIZE; ++i ) {
103
        if ( vl_Vivid.smartClip[i].mode > 0 && color.a > 0 ) {
104 105 106 107
            // Distance from the clipping volume outer surface area
            float dist = 0;
            // Compute clip-factor: 0 = outside, 1 = inside
            float clip_factor = 1.0;
108
            if ( vl_Vivid.smartClip[i].mode == 1 ) { // Sphere
109
                // Compute distance from surface of the sphere
110 111
                float dist_center = length( WP.xyz - vl_Vivid.smartClip[i].sphere.xyz );
                if ( dist_center <= vl_Vivid.smartClip[i].sphere.w ) {
112 113
                    clip_factor = 1.0;
                } else {
114
                    dist = dist_center - vl_Vivid.smartClip[i].sphere.w;
115

116 117
                    if ( vl_Vivid.smartClip[i].fadeRange > 0 ) {
                        clip_factor = 1.0 - dist / vl_Vivid.smartClip[i].fadeRange;
118 119 120 121 122
                        clip_factor = clamp( clip_factor, 0.0, 1.0 );
                    } else {
                        clip_factor = 0.0;
                    }
                }
123
            } else
124 125 126
            if ( vl_Vivid.smartClip[i].mode == 2 ) { // Box
                if ( WP.x <= vl_Vivid.smartClip[i].boxMax.x && WP.y <= vl_Vivid.smartClip[i].boxMax.y && WP.z <= vl_Vivid.smartClip[i].boxMax.z &&
                     WP.x >= vl_Vivid.smartClip[i].boxMin.x && WP.y >= vl_Vivid.smartClip[i].boxMin.y && WP.z >= vl_Vivid.smartClip[i].boxMin.z ) {
127 128 129 130 131 132 133 134
                    // Inside
                    clip_factor = 1.0;
                } else {
                    // Outside
                    float dx = 0;
                    float dy = 0;
                    float dz = 0;
                    // x
135 136
                    if ( WP.x > vl_Vivid.smartClip[i].boxMax.x ) {
                        dx = WP.x - vl_Vivid.smartClip[i].boxMax.x;
137
                    } else
138 139
                    if ( WP.x < vl_Vivid.smartClip[i].boxMin.x ) {
                        dx = vl_Vivid.smartClip[i].boxMin.x - WP.x;
140 141
                    }
                    // y
142 143
                    if ( WP.y > vl_Vivid.smartClip[i].boxMax.y ) {
                        dy = WP.y - vl_Vivid.smartClip[i].boxMax.y;
144
                    } else
145 146
                    if ( WP.y < vl_Vivid.smartClip[i].boxMin.y ) {
                        dy = vl_Vivid.smartClip[i].boxMin.y - WP.y;
147 148
                    }
                    // z
149 150
                    if ( WP.z > vl_Vivid.smartClip[i].boxMax.z ) {
                        dz = WP.z - vl_Vivid.smartClip[i].boxMax.z;
151
                    } else
152 153
                    if ( WP.z < vl_Vivid.smartClip[i].boxMin.z ) {
                        dz = vl_Vivid.smartClip[i].boxMin.z - WP.z;
154 155 156
                    }
                    float dist = length( vec3( dx, dy, dz ) );

157 158
                    if ( vl_Vivid.smartClip[i].fadeRange > 0 ) {
                        clip_factor = 1.0 - dist / vl_Vivid.smartClip[i].fadeRange;
159 160 161 162 163 164
                        clip_factor = clamp( clip_factor, 0.0, 1.0 );
                    } else {
                        clip_factor = 0.0;
                    }
                }
            } else
165
            if ( vl_Vivid.smartClip[i].mode == 3 ) { // Plane
166
                // Compute distance from surface of the sphere
167
                float dist = dot( WP.xyz, vl_Vivid.smartClip[i].plane.xyz ) - vl_Vivid.smartClip[i].plane.w;
168 169 170
                if ( dist >= 0 ) {
                    clip_factor = 1.0;
                } else {
171 172
                    if ( vl_Vivid.smartClip[i].fadeRange > 0 ) {
                        clip_factor = 1.0 - abs( dist ) / vl_Vivid.smartClip[i].fadeRange;
173 174 175 176 177 178 179
                        clip_factor = clamp( clip_factor, 0.0, 1.0 );
                    } else {
                        clip_factor = 0.0;
                    }
                }
            }

180
            if ( vl_Vivid.smartClip[i].reverse == false ) {
181 182 183
                clip_factor = 1.0 - clip_factor;
            }

184
            if ( vl_Vivid.smartClip[i].target == 0 ) { // Color
185
                vec3 lighting = AdjustSaturation( color.xyz, 0.0 );
186
                color.xyz = mix( color.xyz, vl_Vivid.smartClip[i].color.xyz * lighting, clip_factor );
187
            } else
188
            if ( vl_Vivid.smartClip[i].target == 1 ) { // Alpha
189 190
                color.a = color.a * clip_factor;
            } else
191
            if ( vl_Vivid.smartClip[i].target == 2 ) { // Saturation
192 193 194 195 196 197 198 199
                color.xyz = AdjustSaturation( color.xyz, clip_factor );
            }
        }
    }

    return color;
}

200
vec4 FogStage( vec4 color )
201
{
202
    if ( vl_Vivid.smartFog.mode > 0 && color.a > 0 ) {
203 204 205
        // Compute fog factor
        float dist = length( CP.xyz );
        float fog_factor = 0;
206
        if ( vl_Vivid.smartFog.mode == 1 ) {
207 208 209
            // Linear
            fog_factor = ( gl_Fog.end - dist ) * gl_Fog.scale;
        } else
210
        if ( vl_Vivid.smartFog.mode == 2 ) {
211 212 213
            // Exp
            fog_factor = 1.0 / exp( gl_Fog.density * dist );
        } else
214
        if ( vl_Vivid.smartFog.mode == 3 ) {
215 216 217 218 219
            // Exp2
            fog_factor = 1.0 / exp( ( gl_Fog.density * dist ) * ( gl_Fog.density * dist ) );
        }
        fog_factor = clamp( fog_factor, 0, 1.0 );

220
        if (vl_Vivid.smartFog.target == 0) {
221
            // Color
222 223
            color.xyz = mix( gl_Fog.color.xyz, color.xyz, fog_factor );
        } else
224
        if (vl_Vivid.smartFog.target == 1) {
225 226
            // Transparency
            color.a = color.a * fog_factor;
227
        } else
228
        if (vl_Vivid.smartFog.target == 2) {
229
            // Saturation
230 231
            color.xyz = AdjustSaturation( color.xyz, fog_factor );
        }
232 233 234 235 236
    }

    return color;
}

237
vec4 ColorPipeline() {
238
  vec4 color = LightingStage();
239 240 241
  color = ClippingStage(color);
  color = FogStage(color);
  return color;
Michele Bosi's avatar
Michele Bosi committed
242
}