-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
341 lines (290 loc) · 15.4 KB
/
index.html
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" type="text/css" href="css/canvas.css"/>
<title>WEB GL</title>
</head>
<body>
<canvas class="ctx" width="720px" height="720px" onmousedown="drag(event)" onmouseup="stopDrag(event)" onmousemove="mousemove(event)"></canvas>
<script id="Shader-vs" type="x-shader/x-vertex">
attribute vec3 a_Position; // 每个顶点的坐标
attribute vec3 a_Color; // 每个顶点的颜色
attribute vec3 a_Normal; // 每个顶点的法线
attribute vec2 a_texCoord;
uniform mat4 u_ModelMatrix; // Current frame const 模型矩阵
uniform mat4 u_ViewMatrix; // Current frame const 视图矩阵
uniform mat4 u_ProjeMatrix; // Current frame const 投影矩阵
uniform mat4 u_normalMatrix;// Current frame const 逆转置矩阵
varying vec3 v_normal; // 每个片元的法线
varying vec3 v_pos; // 每个片元的位置
varying vec2 v_texCoord; // 每个片元的纹素坐标
varying mat4 v_model;
// varying vec4 v_color; // 每个片元的固有色
void main () {
gl_Position = u_ProjeMatrix * u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1.0);
v_model = u_ModelMatrix;
v_pos = vec3(u_ModelMatrix * vec4(a_Position, 1.0)); // 每个片元的世界坐标
v_normal = normalize(vec3(u_normalMatrix * vec4(a_Normal, 0.0))); // 每个片元的法线
// v_color = vec4(a_Color, 1.0); // 每个片元的固有色
v_texCoord = a_texCoord;
}
</script>
<script id="Shader-fs" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
#define PI 3.1415926535898
precision mediump float;
uniform vec3 u_ambientLight; // Current frame const 环境光颜色
uniform vec3 u_lightColor; // Current frame const 光源颜色
// uniform vec3 u_lightPosition; // Current frame const 光源位置
uniform vec3 u_lightDirection; // Current frame const 光源位置
uniform samplerCube u_sky;
uniform sampler2D brdf; // BRDF LUT
uniform sampler2D uv_Normal;
uniform sampler2D uv_Basecolor;
uniform sampler2D uv_MetallicRoughness;
uniform sampler2D uv_AO;
uniform vec3 u_Camera;
varying mat4 v_model;
uniform sampler2D u_sampler;
varying vec3 v_normal; // 每个片元的法线
varying vec3 v_pos; // 每个片元的位置
varying vec2 v_texCoord; // 每个片元的纹素坐标
// varying vec4 v_color; // 每个片元的固有色
vec3 Fresnel(vec3 f0, float LoN, float roughness) {
return f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - LoN, 5.0);
}
float Distribution(float roughness, float NoH) {
float alpha = roughness * roughness;
float alphaSq = alpha * alpha;
float NoHsqr = NoH * NoH;
return alphaSq / (pow( NoHsqr * alphaSq - NoHsqr + 1.0, 2.0) * PI);;
}
float Geometric(float roughness, float NoL, float NoV) {
float k = pow(roughness + 1.0, 2.0) / 8.0;
float Gl = NoL / ((NoL - NoL * k) + k);
float Gv = NoV / ((NoV - NoV * k) + k);
return Gl * Gv;
}
mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv){
// get edge vectors of the pixel triangle
vec3 dp1 = dFdx( p );
vec3 dp2 = dFdy( p );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
// solve the linear system
vec3 dp2perp = cross( dp2, N );
vec3 dp1perp = cross( N, dp1 );
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
return mat3( T * invmax, B * invmax, N );
}
void main () {
// PBR Material
vec4 PBRBasecolor = texture2D(uv_Basecolor, v_texCoord);
vec4 PBRNormal = texture2D(uv_Normal, v_texCoord);
vec3 PBRMetallic = texture2D(uv_MetallicRoughness, v_texCoord).rgb;
float PBRRoughness = texture2D(uv_MetallicRoughness, v_texCoord).a;
vec4 PBRAO = texture2D(uv_AO, v_texCoord);
vec3 v = normalize(u_Camera - v_pos);
vec3 n = normalize(v_normal);
mat3 TBN = cotangent_frame(n, v, v_texCoord);
vec3 normalAddation = PBRNormal.rgb * 2.0 - 1.0;
n = normalize(TBN * normalAddation);
// vec3 v = normalize(( vec4(u_Camera - v_pos, 0.0)).xyz);
// vec3 l = normalize(u_lightDirection);
vec3 l = normalize((v_model * vec4(u_lightDirection, 0.0)).xyz);
vec3 h = normalize(l+v);
// Fresnel - Specular Reflection
vec3 F;
vec3 f0 = vec3(0.04);
f0 = mix(f0, PBRBasecolor.xyz, PBRMetallic);
float VdotH = dot(v, h);
// Distribution
float D;
float roughness = 0.1;
float NdotH = clamp(dot(n, h), 0.001, 1.0);
float NdotL = clamp(dot(n, l), 0.001, 1.0);
float NdotV = clamp(dot(n, v), 0.001, 0.99);
// float NdotV = abs(dot(n, v));
// D = Distribution(roughness, NdotH);
// Geometric
float G;
// G = Geometric(roughness, NdotL, NdotV);
// vec3 specularContrib = F * G * D / (4.0 * NdotL * NdotV);
// Diffuse
float LdotH = dot(l, h);
float f90 = 2.0 * LdotH * LdotH * roughness - 0.5;
vec3 color = vec3(0.0, 0.4, 0.8);
vec3 specularColor = textureCube(u_sky, (v_model *vec4(reflect(-v,n), 1.0)).xyz).rgb;
// vec3 diffuseContrib = vec3(0.3, 0.8, 0.9) * max(dot(n, l), 0.01); // Lambert
vec2 envBRDF = texture2D(brdf, vec2(NdotV, PBRRoughness)).rg;
vec3 Fre = Fresnel(f0, NdotV, PBRRoughness); // ?required?
vec3 indirectSpecular = specularColor * (Fre * envBRDF.r + envBRDF.g);
// vec3 indirectSpecular = specularColor * (f0 * envBRDF.r + envBRDF.g); // NOTE
// Debug
// gl_FragColor = vec4(Fre, 1.0); // Fresnel
// gl_FragColor = vec4(envBRDF, 0.0 , 1.0); // BRDF LUT
// gl_FragColor = vec4(indirectSpecular, 1.0); // IBL+BRDF
// gl_FragColor = vec4(PBRBasecolor); // UV
// Final Result
gl_FragColor = (vec4((1.0-Fre) * (1.0-PBRMetallic), 1.0) * PBRBasecolor + vec4(indirectSpecular, 1.0)) * PBRAO; // IBL+PBR
}
</script>
<!-- Channel 1 -->
<script id="Shader-ch1-vs" type="x-shader/x-vertex">
attribute vec3 a_Position; // 每个顶点的坐标
attribute vec2 a_texCoord;
varying vec2 v_texCoord; // 每个片元的纹素坐标
uniform mat4 u_ModelMatrix; // Current frame const 模型矩阵
uniform mat4 u_ViewMatrix; // Current frame const 视图矩阵
uniform mat4 u_ProjeMatrix; // Current frame const 投影矩阵
void main () {
// gl_Position = vec4(a_Position, 1.0);
gl_Position = u_ProjeMatrix * u_ViewMatrix * u_ModelMatrix * vec4(a_Position, 1.0);
v_texCoord = a_texCoord;
}
</script>
<script id="Shader-ch1-fs" type="x-shader/x-fragment">
#define PI 3.1415926535898
precision mediump float;
uniform sampler2D u_sampler;
varying vec2 v_texCoord; // 每个片元的纹素坐标
// 采样半径
#define INTENSITY 0.4
#define THRESHOLD 0.1
#define BLUR_SPREAD 3.0/512.0
#define tex(t, uv) fragDownsample(t, uv, BLUR_SPREAD)
float luminance(vec3 rgb) {
const vec3 w = vec3(0.2125, 0.7154, 0.0721);
return dot(rgb, w);
}
// kernel{radius}
mat3 kernel2 = mat3(
0.04952802924382314, 0.04685150823948568, 0.039658945508286664,
0.04685150823948568, 0.044319627851704825, 0.037515755030421205,
0.039658945508286664, 0.037515755030421205, 0.03175640102872468
);
// Blur spread 扩撒
vec4 fragDownsample(sampler2D image, vec2 uv, float _MainTex_TexelSize) {
vec2 uv2[4];
uv2[0] = uv + _MainTex_TexelSize * vec2(1.5, 1.5);
uv2[1] = uv + _MainTex_TexelSize * vec2(-1.5, 1.5);
uv2[2] = uv + _MainTex_TexelSize * vec2(-1.5, -1.5);
uv2[3] = uv + _MainTex_TexelSize * vec2(1.5, -1.5);
vec4 color;
color += texture2D(image, uv2[0]);
color += texture2D(image, uv2[1]);
color += texture2D(image, uv2[2]);
color += texture2D(image, uv2[3]);
return max(color/4.0 - THRESHOLD, vec4(0.0)) * INTENSITY;
}
vec4 fastBlur(sampler2D image, vec2 uv, const int radius, vec2 resolution) {
vec4 blur = vec4(0.0);
vec2 netFilterWidth;
vec2 _offset[7];
vec4 curve[7];
curve[0] = vec4(0.0205, 0.0205, 0.0205, 0.0);
curve[1] = vec4(0.0855, 0.0855, 0.0855, 0.0);
curve[2] = vec4(0.232, 0.232, 0.232, 0.0);
curve[3] = vec4(0.324, 0.324, 0.324, 1.0);
curve[4] = vec4(0.232, 0.232, 0.232, 0.0);
curve[5] = vec4(0.0855, 0.0855, 0.0855, 0.0);
curve[6] = vec4(0.0205, 0.0205, 0.0205, 0.0);
// horizontal blur
netFilterWidth = vec2(1.0 / resolution.x, 0.0);
_offset[0] = uv + netFilterWidth * 3.0;
_offset[1] = uv + netFilterWidth * 2.0;
_offset[2] = uv + netFilterWidth;
_offset[3] = uv;
_offset[4] = uv + netFilterWidth;
_offset[5] = uv + netFilterWidth * 2.0;
_offset[6] = uv + netFilterWidth * 3.0;
for(int l = 0; l < 7; l++) {
blur += tex(image, _offset[l]) * curve[l];
}
// vertical blur
netFilterWidth = vec2(0.0, 1.0 / resolution.y);
_offset[0] = uv + netFilterWidth * 3.0;
_offset[1] = uv + netFilterWidth * 2.0;
_offset[2] = uv + netFilterWidth;
_offset[3] = uv;
_offset[4] = uv + netFilterWidth;
_offset[5] = uv + netFilterWidth * 2.0;
_offset[6] = uv + netFilterWidth * 3.0;
for(int l = 0; l < 7; l++) {
blur += tex(image, _offset[l]) * curve[l];
}
return blur;
}
vec4 fastGaussBlur(sampler2D image, vec2 uv, const int radius, vec2 resolution) {
vec4 blur = vec4(0.0);
if(radius == 1) {
for(int y = -2; y <= 2; y++) {
for(int x = -2; x <= 2; x++) {
vec2 p = uv + vec2(x, y) / resolution * 1.0;
vec4 linearBlur = vec4(0.0);
for(int ly = -1; ly <= 1; ly++) {
for(int lx = -1; lx <= 1; lx++) {
linearBlur += texture2D(image, p + vec2(lx, ly) / resolution) / 9.0;
}
}
blur += linearBlur * kernel2[x<0?-x:x][y<0?-y:y];
}
}
} else if(radius == 2) {
for(int y = -2; y <= 2; y++) {
for(int x = -2; x <= 2; x++) {
vec2 p = uv + vec2(x, y) / resolution * 3.0;
vec4 linearBlur = vec4(0.0);
for(int ly = -3; ly <= 3; ly++) {
for(int lx = -3; lx <= 3; lx++) {
linearBlur += texture2D(image, p + vec2(lx, ly) / resolution) / 49.0;
}
}
blur += linearBlur * kernel2[x<0?-x:x][y<0?-y:y];
}
}
} else if(radius == 3) {
for(int y = -2; y <= 2; y++) {
for(int x = -2; x <= 2; x++) {
vec2 p = uv + vec2(x, y) / resolution * 7.0;
vec4 linearBlur = vec4(0.0);
for(int ly = -7; ly <= 7; ly++) {
for(int lx = -7; lx <= 7; lx++) {
vec4 temp = texture2D(image, p + vec2(lx, ly) / resolution);
if(luminance(temp.rgb) >= THRESHOLD) {
linearBlur += temp / 225.0;
}
temp = vec4(0.0, 0.0, 0.0, 0.0);
}
}
blur += linearBlur * kernel2[x<0?-x:x][y<0?-y:y];
}
}
}
blur = vec4(blur.rgb * INTENSITY, blur.a);
return blur * luminance(texture2D(image, uv).rgb);
}
void main () {
vec2 texcoord = vec2(v_texCoord);
vec4 c = texture2D(u_sampler, texcoord);
vec4 cur_color;
// cur_color = fastGaussBlur(u_sampler, texcoord, 3, vec2(720));
// cur_color = fastBlur(u_sampler, texcoord, 3, vec2(210));
cur_color = fastBlur(u_sampler, texcoord, 3, vec2(128.0));
float lum = luminance(cur_color.rgb);
float _lum = luminance(c.rgb);
// gl_FragColor = cur_color;
c = vec4(c.rgb * INTENSITY, c.a);
gl_FragColor = c + cur_color;
}
</script>
<script src="scripts/cuon-matrix.js"></script>
<!-- <script src="scripts/brs-matrix.js"></script> -->
<script src="scripts/canvas.js"></script>
</body>
</html>