summaryrefslogtreecommitdiff
path: root/engine/light.glsl
blob: 1bc23a436c9ee8a37b4e0c930f8ae3cc35af72e6 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#version 330 core

#ifndef LIGHT_GLSL
#define LIGHT_GLSL

#preinclude "vertex_data.glsl"

struct Material
{
	vec3 ambient;
	vec3 diffuse;
	vec3 specular;
	sampler2D ambient_map;
	sampler2D diffuse_map;
	sampler2D specular_map;
	float shininess;
};

struct LightPhong
{
	vec3 diffuse;
	vec3 specular;
};

struct AttenuationProperties
{
	float constant;
	float linear;
	float quadratic;
};

struct PointLight
{
	LightPhong phong;
	vec3 position;
	AttenuationProperties attenuation_props;
};

struct DirectionalLight
{
	LightPhong phong;
	vec3 direction;
};

struct CalculatedLight
{
	vec3 diffuse;
	vec3 specular;
};

vec3 calc_ambient_light(in Material material, in vec2 texture_coords)
{
	return vec3(texture(material.ambient_map, texture_coords)) * material.ambient;
}

vec3 calc_diffuse_light(
	in Material material,
	in LightPhong light_phong,
	in vec3 light_dir,
	in vec3 norm,
	in vec2 texture_coords
)
{
	float diff = max(dot(norm, light_dir), 0.0);

	return light_phong.diffuse * (
		diff * (vec3(texture(material.diffuse_map, texture_coords)) * material.diffuse)
	);
}

vec3 calc_specular_light(
	in Material material,
	in LightPhong light_phong,
	in vec3 light_dir,
	in vec3 norm,
	in vec3 view_pos,
	in vec3 frag_pos,
	in vec2 texture_coords
)
{
	vec3 view_direction = normalize(view_pos - frag_pos);

	vec3 reflect_direction = reflect(-light_dir, norm);

	float spec =
		pow(max(dot(view_direction, reflect_direction), 0.0), material.shininess);

	return light_phong.specular * (
		spec * (vec3(texture(material.specular_map, texture_coords)) * material.specular)
	);
}

float calc_attenuation(in PointLight point_light, in vec3 position)
{
	float light_distance = length(point_light.position - position);

	return 1.0 / (point_light.attenuation_props.constant
		+ point_light.attenuation_props.linear
		* light_distance + point_light.attenuation_props.quadratic
		* pow(light_distance, 2));
}

void calc_light(
	in vec3 light_direction,
	in LightPhong light_phong,
	in VertexData vertex_data,
	in vec3 view_pos,
	in Material material,
	out CalculatedLight calculated_light
)
{
	vec3 norm = normalize(vertex_data.world_space_normal);

	calculated_light.diffuse = calc_diffuse_light(
		material,
		light_phong,
		light_direction,
		norm,
		vertex_data.texture_coords
	);

	calculated_light.specular = calc_specular_light(
		material,
		light_phong,
		light_direction,
		norm,
		view_pos,
		vertex_data.world_space_pos,
		vertex_data.texture_coords
	);
}

#endif