1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
const int MAX_LIGHTS = 2; // RPi: cannot use more than two as we run out of uniforms
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
const int TYPE_SPOT = 2;
struct Light {
int type;
FP vec3 position;
FP vec3 color;
FP float intensity;
FP vec3 direction;
FP vec3 attenuation;
FP float cutOffAngle;
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
out FP vec3 diffuseColor, out FP vec3 specularColor)
{
diffuseColor = vec3(0.0);
specularColor = vec3(0.0);
FP vec3 n = normalize( vnormal );
// 0
if (lightCount < 1)
return;
FP vec3 s;
FP float att = 1.0;
if ( lights[0].type != TYPE_DIRECTIONAL ) {
s = lights[0].position - vpos;
if (length( lights[0].attenuation ) != 0.0) {
FP float dist = length(s);
att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
}
s = normalize( s );
if ( lights[0].type == TYPE_SPOT ) {
if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
att = 0.0;
}
} else {
s = normalize( -lights[0].direction );
}
FP float diffuse = max( dot( s, n ), 0.0 );
FP float specular = 0.0;
if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
FP vec3 r = reflect( -s, n );
FP vec3 v = normalize( eye - vpos );
FP float normFactor = ( shininess + 2.0 ) / 2.0;
specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
}
diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
specularColor += att * specular;
// 1
if (lightCount < 2)
return;
att = 1.0;
if ( lights[1].type != TYPE_DIRECTIONAL ) {
s = lights[1].position - vpos;
if (length( lights[1].attenuation ) != 0.0) {
FP float dist = length(s);
att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
}
s = normalize( s );
if ( lights[1].type == TYPE_SPOT ) {
if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
att = 0.0;
}
} else {
s = normalize( -lights[1].direction );
}
diffuse = max( dot( s, n ), 0.0 );
specular = 0.0;
if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
FP vec3 r = reflect( -s, n );
FP vec3 v = normalize( eye - vpos );
FP float normFactor = ( shininess + 2.0 ) / 2.0;
specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
}
diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
specularColor += att * specular;
}
|