-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphongFog.frag
182 lines (141 loc) · 5.54 KB
/
phongFog.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
precision highp float;
//precision highp int;
uniform mat4 uViewMatrix;
uniform bool uUseLighting;
uniform int uAmbientLightCount;
uniform vec3 uAmbientColor[5];
uniform int uDirectionalLightCount;
uniform vec3 uLightingDirection[5];
uniform vec3 uDirectionalDiffuseColors[5];
uniform vec3 uDirectionalSpecularColors[5];
uniform int uPointLightCount;
uniform vec3 uPointLightLocation[5];
uniform vec3 uPointLightDiffuseColors[5];
uniform vec3 uPointLightSpecularColors[5];
uniform int uSpotLightCount;
uniform float uSpotLightAngle[5];
uniform float uSpotLightConc[5];
uniform vec3 uSpotLightDiffuseColors[5];
uniform vec3 uSpotLightSpecularColors[5];
uniform vec3 uSpotLightLocation[5];
uniform vec3 uSpotLightDirection[5];
uniform bool uSpecular;
uniform float uShininess;
uniform float uConstantAttenuation;
uniform float uLinearAttenuation;
uniform float uQuadraticAttenuation;
const float specularFactor = 2.0;
const float diffuseFactor = 0.73;
struct LightResult {
float specular;
float diffuse;
};
float _phongSpecular(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal, float shininess) {
vec3 R = reflect(lightDirection, surfaceNormal);
return pow(max(0.0, dot(R, viewDirection)), shininess);
}
float _lambertDiffuse(vec3 lightDirection, vec3 surfaceNormal) {
return max(0.0, dot(-lightDirection, surfaceNormal));
}
LightResult _light(vec3 viewDirection, vec3 normal, vec3 lightVector) {
vec3 lightDir = normalize(lightVector);
//compute our diffuse & specular terms
LightResult lr;
if (uSpecular) {
lr.specular = _phongSpecular(lightDir, viewDirection, normal, uShininess);
}
lr.diffuse = _lambertDiffuse(lightDir, normal);
return lr;
}
void totalLight(
vec3 modelPosition,
vec3 normal,
out vec3 totalDiffuse,
out vec3 totalSpecular
) {
totalSpecular = vec3(0.0);
if (!uUseLighting) {
totalDiffuse = vec3(1.0);
return;
}
totalDiffuse = vec3(0.0);
vec3 viewDirection = normalize(-modelPosition);
for (int j = 0; j < 5; j++) {
if (j < uDirectionalLightCount) {
vec3 lightVector = (uViewMatrix * vec4(uLightingDirection[j], 0.0)).xyz;
vec3 lightColor = uDirectionalDiffuseColors[j];
vec3 specularColor = uDirectionalSpecularColors[j];
LightResult result = _light(viewDirection, normal, lightVector);
totalDiffuse += result.diffuse * lightColor;
totalSpecular += result.specular * lightColor * specularColor;
}
if (j < uPointLightCount) {
vec3 lightPosition = (uViewMatrix * vec4(uPointLightLocation[j], 1.0)).xyz;
vec3 lightVector = modelPosition - lightPosition;
//calculate attenuation
float lightDistance = length(lightVector);
float lightFalloff = 1.0 / (uConstantAttenuation + lightDistance * uLinearAttenuation + (lightDistance * lightDistance) * uQuadraticAttenuation);
vec3 lightColor = lightFalloff * uPointLightDiffuseColors[j];
vec3 specularColor = lightFalloff * uPointLightSpecularColors[j];
LightResult result = _light(viewDirection, normal, lightVector);
totalDiffuse += result.diffuse * lightColor;
totalSpecular += result.specular * lightColor * specularColor;
}
if(j < uSpotLightCount) {
vec3 lightPosition = (uViewMatrix * vec4(uSpotLightLocation[j], 1.0)).xyz;
vec3 lightVector = modelPosition - lightPosition;
float lightDistance = length(lightVector);
float lightFalloff = 1.0 / (uConstantAttenuation + lightDistance * uLinearAttenuation + (lightDistance * lightDistance) * uQuadraticAttenuation);
vec3 lightDirection = (uViewMatrix * vec4(uSpotLightDirection[j], 0.0)).xyz;
float spotDot = dot(normalize(lightVector), normalize(lightDirection));
float spotFalloff;
if(spotDot < uSpotLightAngle[j]) {
spotFalloff = 0.0;
}
else {
spotFalloff = pow(spotDot, uSpotLightConc[j]);
}
lightFalloff *= spotFalloff;
vec3 lightColor = uSpotLightDiffuseColors[j];
vec3 specularColor = uSpotLightSpecularColors[j];
LightResult result = _light(viewDirection, normal, lightVector);
totalDiffuse += result.diffuse * lightColor * lightFalloff;
totalSpecular += result.specular * lightColor * specularColor * lightFalloff;
}
}
totalDiffuse *= diffuseFactor;
totalSpecular *= specularFactor;
}
uniform float uFogEnabled;
uniform vec3 uFogColor;
uniform float uFogStart;
uniform float uFogEnd;
float fog_linear(float dist, float start, float end) {
return 1.0 - clamp((end - dist) / (end - start), 0.0, 1.0);
}
uniform vec4 uSpecularMatColor;
uniform vec4 uAmbientMatColor;
uniform vec4 uEmissiveMatColor;
uniform vec4 uMaterialColor;
uniform vec4 uTint;
uniform sampler2D uSampler;
uniform bool isTexture;
varying vec3 vNormal;
varying vec2 vTexCoord;
varying vec3 vViewPosition;
varying vec3 vAmbientColor;
void main(void) {
vec3 diffuse;
vec3 specular;
totalLight(vViewPosition, normalize(vNormal), diffuse, specular);
// Calculating final color as result of all lights (plus emissive term).
gl_FragColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
gl_FragColor.rgb = diffuse * gl_FragColor.rgb +
vAmbientColor * uAmbientMatColor.rgb +
specular * uSpecularMatColor.rgb +
uEmissiveMatColor.rgb;
// fog
float fogDistance = gl_FragCoord.z / gl_FragCoord.w;
float fogAmount = fog_linear(fogDistance, uFogStart, uFogEnd);
gl_FragColor.rgb = mix(gl_FragColor.rgb, uFogColor, fogAmount*uFogEnabled);
}