-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshader.frag
159 lines (119 loc) · 4.45 KB
/
shader.frag
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#version 460
struct Material {
// sampler2D diffuse;
// sampler2D specular;
float shininess;
};
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct SpotLight {
vec3 position;
vec3 direction;
float cut_off;
float outer_cut_off;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
layout (location = 0) in vec3 normal;
layout (location = 1) in vec3 frag_pos;
layout (location = 2) in vec2 tex_coords;
layout (location = 0) out vec4 frag_color;
uniform sampler2D texture_diffuse1;
uniform sampler2D texture_specular1;
uniform vec3 camera_pos;
uniform Material material;
uniform DirLight dir_light;
uniform SpotLight spot_light;
uniform PointLight point_light;
vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_dir);
vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_pos, vec3 view_dir);
vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_pos, vec3 view_dir);
void main()
{
// properties
vec3 norm = normalize(normal);
vec3 view_dir = normalize(camera_pos - frag_pos);
// directional lighting
vec3 result = calc_dir_light(dir_light, norm, view_dir);
// point light
result += calc_point_light(point_light, norm, frag_pos, view_dir);
// spot light
result += calc_spot_light(spot_light, norm, frag_pos, view_dir);
frag_color = vec4(result, 1.0);
}
vec3 calc_dir_light(DirLight light, vec3 normal, vec3 view_dir)
{
vec3 light_dir = normalize(-light.direction);
// diffuse shading
float diff = max(dot(normal, light_dir), 0.0);
// specular shading
vec3 reflect_dir = reflect(-light_dir, normal);
float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess);
// combine results
vec3 ambient = light.ambient * vec3(texture(texture_diffuse1, tex_coords));
vec3 diffuse = light.diffuse * diff * vec3(texture(texture_diffuse1, tex_coords));
vec3 specular = light.specular * spec * vec3(texture(texture_specular1, tex_coords));
return (ambient + diffuse + specular);
}
vec3 calc_point_light(PointLight light, vec3 normal, vec3 frag_pos, vec3 view_dir)
{
vec3 light_dir = normalize(light.position - frag_pos);
// diffuse shading
float diff = max(dot(normal, light_dir), 0.0);
// specular shading
vec3 reflect_dir = reflect(-light_dir, normal);
float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - frag_pos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
// combine results
vec3 ambient = light.ambient * vec3(texture(texture_diffuse1, tex_coords));
vec3 diffuse = light.diffuse * diff * vec3(texture(texture_diffuse1, tex_coords));
vec3 specular = light.specular * spec * vec3(texture(texture_specular1, tex_coords));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 frag_pos, vec3 view_dir)
{
vec3 light_dir = normalize(light.position - frag_pos);
// diffuse shading
float diff = max(dot(normal, light_dir), 0.0);
// specular shading
vec3 reflect_dir = reflect(-light_dir, normal);
float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - frag_pos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// spotlight intensity
float theta = dot(light_dir, normalize(-light.direction));
float epsilon = light.cut_off - light.outer_cut_off;
float intensity = clamp((theta - light.outer_cut_off) / epsilon, 0.0, 1.0);
// combine results
vec3 ambient = light.ambient * vec3(texture(texture_diffuse1, tex_coords));
vec3 diffuse = light.diffuse * diff * vec3(texture(texture_diffuse1, tex_coords));
vec3 specular = light.specular * spec * vec3(texture(texture_specular1, tex_coords));
ambient *= attenuation * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);
}