File: grim_actor.vertex

package info (click to toggle)
residualvm 0.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: bullseye
  • size: 31,292 kB
  • sloc: cpp: 227,029; sh: 7,256; xml: 1,731; perl: 1,067; java: 861; asm: 738; python: 691; ansic: 272; makefile: 139; objc: 81; sed: 22; php: 1
file content (102 lines) | stat: -rw-r--r-- 2,772 bytes parent folder | download | duplicates (2)
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
const float CONSTANT_ATTENUATION = 1.0;
const float LINEAR_ATTENUATION = 0.0;
const float QUADRATIC_ATTENUATION = 1.0;

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 bool textured;
uniform bool lightsEnabled;
uniform highp vec2 texScale;

struct Light {
	vec4 _position;
	vec4 _direction;
	vec4 _color;
	vec4 _params;
};
const int maxLights = 8;
uniform Light lights[maxLights];

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

uniform shadow_info shadow;

out vec2 Texcoord;
out vec4 Color;

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

	// See http://en.wikipedia.org/wiki/Line-plane_intersection
	if (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);
	}

	vec4 positionView = viewMatrix * pos;
	gl_Position = projMatrix * positionView;

	if (shadow._active) {
		Color = vec4(shadow._color, 1.0);
	} else {
		Color = color;
	}

	if (textured) {
		Texcoord = vec2(0.0, 1.0) + (texcoord / texScale);
	} else {
		Texcoord = vec2(0.0, 0.0);
	}

	if (lightsEnabled) {
		vec3 light = vec3(0.0, 0.0, 0.0);
		vec3 normalEye = normalize((viewMatrix * (modelMatrix * extraMatrix * vec4(normal, 0.0))).xyz);

		for (int i = 0; i < maxLights; ++i) {
			float intensity = lights[i]._color.w;
			float light_type = lights[i]._position.w;
			if (light_type >= 0.0) { // Not ambient
				vec3 vertexToLight = lights[i]._position.xyz;
				if (light_type > 0.0) { // positional light
					vertexToLight -= positionView.xyz;
					float dist = length(vertexToLight);
					intensity /= CONSTANT_ATTENUATION + dist * (LINEAR_ATTENUATION + dist * QUADRATIC_ATTENUATION);
					if (lights[i]._direction.w > -1.0) { // Spotlight
						// See DirectX spotlight documentation
						float cosAngle = -dot(normalize(vertexToLight), normalize(lights[i]._direction.xyz)); // rho
						float cosPenumbra = clamp(lights[i]._params.w, 0.0, 1.0); // cos(theta / 2)
						float cosUmbra = clamp(lights[i]._params.z, 0.0, cosPenumbra); // cos(phi / 2)
						if (cosAngle <= cosPenumbra) {
							if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
								intensity = 0.0;
							} else {
								intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
							}
						}
					}
				}
				intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
			}
			light += lights[i]._color.xyz * intensity;
		}
		light /= max(1.0, max(max(light.x, light.y), light.z));
		Color *= vec4(light, 1.0);
	}
}