summaryrefslogtreecommitdiff
path: root/engine/light.glsl
blob: 9f51237769c781dc4c4d017144f621ff6095d919 (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
#version 330 core

#ifndef LIGHT_GLSL
#define LIGHT_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;
};

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

vec3 calc_point_light(
	in PointLight light,
	in vec3 frag_pos,
	in vec3 normal,
	in vec2 texture_coords,
	in vec3 view_pos,
	in Material material
)
{
	vec3 light_direction = normalize(light.position - frag_pos);
	vec3 norm = normalize(normal);

	vec3 diffuse_light = calc_diffuse_light(
		material,
		light.phong,
		light_direction,
		norm,
		texture_coords
	);

	vec3 specular_light = calc_specular_light(
		material,
		light.phong,
		light_direction,
		norm,
		view_pos,
		frag_pos,
		texture_coords
	);

	float attenuation = calc_attenuation(light, frag_pos);

	diffuse_light *= attenuation;
	specular_light *= attenuation;

	return diffuse_light + specular_light;
}

#endif