File: emi_actorlights.vertex

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (115 lines) | stat: -rw-r--r-- 3,148 bytes parent folder | download | duplicates (3)
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
113
114
115
in vec3 position;
in vec2 texcoord;
in vec4 color;
in vec3 normal;

uniform highp mat4 modelMatrix;
uniform highp mat4 viewMatrix;
uniform highp mat4 projMatrix;
uniform highp mat4 extraMatrix;
uniform highp mat4 normalMatrix;
uniform highp vec3 cameraPos;
uniform UBOOL textured;
uniform UBOOL useVertexAlpha;
uniform vec4 uniformColor;
uniform UBOOL hasAmbient;

const int maxLights = 8;
uniform vec4 lightsPosition[maxLights];
uniform vec4 lightsDirection[maxLights];
uniform vec4 lightsColor[maxLights];
uniform vec4 lightsParams[maxLights];

struct shadow_info {
	UBOOL _active;
	vec3 _color;
	vec3 _light;
	vec3 _point;
	vec3 _normal;
};

uniform shadow_info shadow;

out vec2 Texcoord;
out vec4 Color;

void main() {
	vec4 pos = vec4(position, 1.0);
	pos = modelMatrix * pos;

	// See http://en.wikipedia.org/wiki/Line-plane_intersection
	if (UBOOL_TEST(shadow._active)) {
		pos /= pos.w;
		vec3 l = pos.xyz - shadow._light;
		float d = dot(shadow._point - shadow._light, shadow._normal) / dot(l, shadow._normal);
		vec3 p = shadow._light + d * l;
		pos = vec4(p, 1.0);
	}

	pos -= vec4(cameraPos * pos.w, 0.0);
	pos = viewMatrix * pos;
	pos /= pos.w;
	pos.z *= -1.0;

	vec4 projectedPos = projMatrix * pos;

	gl_Position = projectedPos;

	if (UBOOL_TEST(shadow._active)) {
		Color = vec4(shadow._color, 1.0);
	} else {
		Color = color;
	}
	if (!UBOOL_TEST(useVertexAlpha))
		Color.a = 1.0;
	Color *= uniformColor;
	if (UBOOL_TEST(textured)) {
		Texcoord = texcoord;
	} else {
		Texcoord = vec2(0.0, 0.0);
	}

	vec3 light = vec3(0.0, 0.0, 0.0);
	vec3 normalEye = normalize((normalMatrix * vec4(normal, 1.0)).xyz);

	for (int i = 0; i < maxLights; ++i) {
		float intensity = lightsColor[i].w;
		float light_type = lightsPosition[i].w;
		if (light_type >= 0.0) { // Not ambient
			vec3 vertexToLight;
			if (light_type > 0.0) { // positional light
				float falloffNear = lightsParams[i].x;
				float falloffFar = max(falloffNear, lightsParams[i].y);
				vertexToLight = lightsPosition[i].xyz - pos.xyz;
				float dist = length(vertexToLight);
				if (falloffFar == falloffNear) {
					intensity = 0.0;
				} else {
					intensity *= clamp(1.0 - (dist - falloffNear) / (falloffFar - falloffNear), 0.0, 1.0);
				}
				if (lightsDirection[i].w > -1.0) { // Spotlight
					// See DirectX spotlight documentation
					float cosAngle = -dot(normalize(vertexToLight), normalize(lightsDirection[i].xyz)); // rho
					float cosPenumbra = clamp(lightsParams[i].w, 0.0, 1.0); // cos(theta / 2)
					float cosUmbra = clamp(lightsParams[i].z, 0.0, cosPenumbra); // cos(phi / 2)
					if (cosAngle <= cosPenumbra) {
						if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
							intensity = 0.0;
						} else {
							intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
						}
					}
				}
			} else { // directional light
				vertexToLight = -lightsPosition[i].xyz;
			}
			intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
		}
		light += lightsColor[i].xyz * intensity;
	}

	if (!UBOOL_TEST(hasAmbient))
		light += vec3(0.5, 0.5, 0.5);
	light /= max(1.0, max(max(light.x, light.y), light.z));
	Color *= vec4(light, 1.0);
}