1//
2// Fragment shader for procedurally generated toy ball
3//
4// Author: Bill Licea-Kane
5//
6// Copyright (c) 2002-2003 ATI Research 
7//
8// See ATI-License.txt for license information
9//
10
11varying vec4 ECposition;   // surface position in eye coordinates
12varying vec4 ECballCenter; // ball center in eye coordinates
13
14uniform vec4  LightDir;     // light direction, should be normalized
15uniform vec4  HVector;      // reflection vector for infinite light source
16uniform vec4  SpecularColor;
17uniform vec4  Red, Yellow, Blue;
18
19uniform vec4  HalfSpace0;   // half-spaces used to define star pattern
20uniform vec4  HalfSpace1;
21uniform vec4  HalfSpace2;
22uniform vec4  HalfSpace3;
23uniform vec4  HalfSpace4;
24
25uniform float InOrOutInit;  // = -3
26uniform float StripeWidth;  // = 0.3
27uniform float FWidth;       // = 0.005
28
29void main()
30{
31    vec4  normal;              // Analytically computed normal
32    vec4  p;                   // Point in shader space
33    vec4  surfColor;           // Computed color of the surface
34    float intensity;           // Computed light intensity
35    vec4  distance;            // Computed distance values
36    float inorout;             // Counter for computing star pattern
37
38    p.xyz = normalize(ECposition.xyz - ECballCenter.xyz);    // Calculate p
39    p.w   = 1.0;
40
41    inorout = InOrOutInit;     // initialize inorout to -3
42
43    distance[0] = dot(p, HalfSpace0);
44    distance[1] = dot(p, HalfSpace1);
45    distance[2] = dot(p, HalfSpace2);
46    distance[3] = dot(p, HalfSpace3);
47
48    distance = smoothstep(-FWidth, FWidth, distance);
49    inorout += dot(distance, vec4(1.0));
50
51    distance.x = dot(p, HalfSpace4);
52    distance.y = StripeWidth - abs(p.z);
53    distance = smoothstep(-FWidth, FWidth, distance);
54    inorout += distance.x;
55
56    inorout = clamp(inorout, 0.0, 1.0);
57
58    surfColor = mix(Yellow, Red, inorout);
59    surfColor = mix(surfColor, Blue, distance.y);
60
61    // normal = point on surface for sphere at (0,0,0)
62    normal = p;
63
64    // Per fragment diffuse lighting
65    intensity  = 0.2; // ambient
66    intensity += 0.8 * clamp(dot(LightDir, normal), 0.0, 1.0);
67    surfColor *= intensity;
68
69    // Per fragment specular lighting
70    intensity  = clamp(dot(HVector, normal), 0.0, 1.0);
71    intensity  = pow(intensity, SpecularColor.a);
72    surfColor += SpecularColor * intensity;
73
74    gl_FragColor = surfColor;
75}
76