aboutsummaryrefslogtreecommitdiff
path: root/data/shaders/lighting.frag
blob: d3e35345f52d33e5e1911eb49254832396df039c (plain)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * lighting.frag
 *
 * Lighting calculations
 *
 * (c) 2007-2008 Thomas White <taw27@cam.ac.uk>
 *
 *  thrust3d - a silly game
 *
 */

varying vec3 pos;
varying vec3 normal;

varying vec3 light0vc;
varying float light0dist;

varying vec3 light1vc;
varying vec3 light2vc;

uniform sampler2D texture;
uniform sampler2D normalmap;

uniform bool has_normals;
uniform bool fill_light_enabled;
uniform bool texture_enabled;
uniform bool texture_emits;
uniform float alpha;

varying vec3 col_ambi_diff;
varying vec3 col_emit;

void main() {
	
	vec3 ambi;
	vec3 emit;
	vec3 diff = vec3(0.0, 0.0, 0.0);
	vec3 spec = vec3(0.0, 0.0, 0.0);
	vec3 norm = normal;
	
	if ( has_normals ) {
		norm += (texture2D(normalmap, gl_TexCoord[0].st).rgb - vec3(0.5, 0.5, 0.5)) / 2.0;
	}
	
	norm = normalize(norm);
	
	/* Ambient */
	ambi = col_ambi_diff * gl_LightModel.ambient.rgb;
	
	/* Emission */
	emit = col_emit;
		
	if ( fill_light_enabled ) {
		
		/* Light 2: Fill-in light for lander */
		float diff_fac, spec_fac;
		
		diff_fac = max(dot(norm, normalize(light2vc)), 0.0);
		diff += col_ambi_diff * gl_LightSource[2].diffuse.rgb * diff_fac;
		
	} else {
	
		/* Light 0: Lander craft's spotlight */
		float falloff, spot;
		float diff_fac, spec_fac;
		vec3 E, R;
		
		falloff = 1/ (  gl_LightSource[0].constantAttenuation
			            + gl_LightSource[0].linearAttenuation * light0dist
			            + gl_LightSource[0].quadraticAttenuation * light0dist * light0dist );
		
		spot = max(dot(normalize(-light0vc), gl_LightSource[0].spotDirection), 0.0);
		spot = pow(spot, gl_LightSource[0].spotExponent);
		
		diff_fac = max(0.0, dot(norm, normalize(light0vc)));
		diff += col_ambi_diff * gl_LightSource[0].diffuse.rgb * spot * falloff * diff_fac;
		
		E = normalize(-pos);
		R = normalize(-reflect(light0vc, norm)); 
		
		spec_fac = pow(max(0.0, dot(R, E)), 80.0);
		spec += vec3(1.0, 1.0, 1.0) * gl_LightSource[0].specular.rgb * spot * falloff * spec_fac;
		
		/* Light 1: Background glow */
		diff += col_ambi_diff * gl_LightSource[1].diffuse.rgb * max(0.0, dot(vec3(light1vc), norm));

	}
	
	if ( texture_enabled ) {
	
		vec3 tex = texture2D(texture, gl_TexCoord[0].st).rgb;
		
		if ( texture_emits ) {
			gl_FragColor = vec4(tex.r, tex.g, tex.b, alpha);
		} else {
			gl_FragColor = vec4(min(tex.r * (ambi.r + diff.r) + spec.r, 1.0),
					    min(tex.g * (ambi.g + diff.g) + spec.g, 1.0),
					    min(tex.b * (ambi.b + diff.b) + spec.b, 1.0),
					    alpha);
		}
	
	} else {

		gl_FragColor = vec4(min(emit.r + ambi.r + diff.r + spec.r, 1.0),
				    min(emit.g + ambi.g + diff.g + spec.g, 1.0),
				    min(emit.b + ambi.b + diff.b + spec.b, 1.0),
				    alpha);

	}

}