summaryrefslogtreecommitdiff
path: root/gfx/gl/shaders/spotLight.gs
blob: 05296140be9f3e44663f2241271d8af5948f243c (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
#version 330 core
#extension GL_ARB_enhanced_layouts : enable
#extension GL_ARB_shading_language_420pack : enable

const vec3[] pyramid = vec3[]( // four-sided
		vec3(0, 0, 0), // Apex
		vec3(-1, 1, 1), // Back-left
		vec3(-1, -1, 1), // Front-left
		vec3(1, 1, 1), // Back-right
		vec3(1, -1, 1) // Front-right
);
uniform mat4 viewProjection;
uniform vec3 viewPoint;
uniform float arc;

in vec3 position[];
in vec3 direction[];
in float size[];
in float cosarc[];
layout(points) in;

layout(triangle_strip, max_vertices = 8) out;
out vec4 geo_centre;
out vec4 geo_direction;

vec3
perp(vec3 a)
{
	return normalize(a.x != 0  ? vec3((a.y + a.z) / -a.x, 1, 1)
					: a.y != 0 ? vec3(1, (a.x + a.z) / -a.y, 1)
							   : vec3(1, 1, (a.x + a.y) / -a.z));
}

void
doVertex(vec4 ndcpos)
{
	gl_Position = ndcpos;
	geo_centre = vec4(position[0], size[0]);
	geo_direction = vec4(direction[0], cosarc[0]);
	EmitVertex();
}

void
main()
{
	const float base = size[0] * tan(arc / 2);
	const vec3 offx = perp(direction[0]);
	const vec3 offy = cross(direction[0], offx);
	vec4 out_py[pyramid.length()];
	for (int i = 0; i < pyramid.length(); ++i) {
		const vec3 p = pyramid[i];
		const vec3 edge = (offx * base * p.x) + (offy * base * p.y) + (direction[0] * size[0] * p.z);
		out_py[i] = viewProjection * (gl_in[0].gl_Position + vec4(edge, 1));
	}
	doVertex(out_py[3]);
	doVertex(out_py[0]);
	doVertex(out_py[1]);
	doVertex(out_py[2]);
	doVertex(out_py[3]);
	doVertex(out_py[4]);
	doVertex(out_py[0]);
	doVertex(out_py[2]);
	EndPrimitive();
}