File: emi_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 (134 lines) | stat: -rw-r--r-- 3,490 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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 bool textured;
uniform bool isBillboard;
uniform bool useVertexAlpha;
uniform vec4 uniformColor;
uniform bool lightsEnabled;
uniform bool hasAmbient;

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 = vec4(position, 1.0);
	if (isBillboard) {
		vec4 offset = modelMatrix * vec4(0.0, 0.0, 0.0, 1.0);
		offset -= vec4(cameraPos * offset.w, 0.0);
		offset = viewMatrix * offset;

		pos = extraMatrix * pos;
		pos += vec4(offset.xyz * pos.w, 0.0);
	} else {
		pos = modelMatrix * pos;

		// 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);
		}

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

	vec4 projectedPos = projMatrix * pos;
	if (isBillboard)
		projectedPos.z = round(projectedPos.z);

	gl_Position = projectedPos;

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

	if (lightsEnabled) {
		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 = lights[i]._color.w;
			float light_type = lights[i]._position.w;
			if (light_type >= 0.0) { // Not ambient
				vec3 vertexToLight;
				if (light_type > 0.0) { // positional light
					float falloffNear = lights[i]._params.x;
					float falloffFar = max(falloffNear, lights[i]._params.y);
					vertexToLight = lights[i]._position.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 (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);
							}
						}
					}
				} else { // directional light
					vertexToLight = -lights[i]._position.xyz;
				}
				intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
			}
			light += lights[i]._color.xyz * intensity;
		}

		if (!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);
	}
}