@@ -14,18 +14,18 @@ import {
14
14
*
15
15
* - other AO algorithms that are not implemented here:
16
16
* - Screen Space Ambient Occlusion (SSAO), see also SSAOShader.js
17
- * - http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html
18
- * - https://learnopengl.com/Advanced-Lighting/SSAO
19
- * - https://creativecoding.soe.ucsc.edu/courses/cmpm164/_schedule/AmbientOcclusion.pdf
20
- * - https://drive.google.com/file/d/1SyagcEVplIm2KkRD3WQYSO9O0Iyi1hfy/edit
17
+ * - http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html
18
+ * - https://learnopengl.com/Advanced-Lighting/SSAO
19
+ * - https://creativecoding.soe.ucsc.edu/courses/cmpm164/_schedule/AmbientOcclusion.pdf
20
+ * - https://drive.google.com/file/d/1SyagcEVplIm2KkRD3WQYSO9O0Iyi1hfy/edit
21
21
* - Scalable Ambient Occlusion (SAO), see also SAOShader.js
22
- * - https://casual-effects.com/research/McGuire2012SAO/index.html
22
+ * - https://casual-effects.com/research/McGuire2012SAO/index.html
23
23
* - https://research.nvidia.com/sites/default/files/pubs/2012-06_Scalable-Ambient-Obscurance/McGuire12SAO.pdf
24
24
* - N8HO
25
- * - https://github.com/N8python/n8ao
25
+ * - https://github.com/N8python/n8ao
26
26
* - Horizon Based Ambient Occlusion (HBAO)
27
- * - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.577.2286&rep=rep1&type=pdf
28
- * - https://www.derschmale.com/2013/12/20/an-alternative-implementation-for-hbao-2/
27
+ * - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.577.2286&rep=rep1&type=pdf
28
+ * - https://www.derschmale.com/2013/12/20/an-alternative-implementation-for-hbao-2/
29
29
*
30
30
* - further reading
31
31
* - https://ceur-ws.org/Vol-3027/paper5.pdf
@@ -66,7 +66,7 @@ const GTAOShader = {
66
66
bias : { value : 0.001 } ,
67
67
scale : { value : 1. } ,
68
68
sceneBoxMin : { value : new Vector3 ( - 1 , - 1 , - 1 ) } ,
69
- sceneBoxMax : { value : new Vector3 ( 1 , 1 , 1 ) } ,
69
+ sceneBoxMax : { value : new Vector3 ( 1 , 1 , 1 ) } ,
70
70
} ,
71
71
72
72
vertexShader : /* glsl */ `
@@ -130,27 +130,25 @@ const GTAOShader = {
130
130
}
131
131
132
132
vec3 computeNormalFromDepth(const vec2 uv) {
133
- vec2 size = vec2(textureSize(tDepth, 0));
134
- ivec2 p = ivec2(uv * size);
135
- float c0 = fetchDepth(p);
136
- float l2 = fetchDepth(p - ivec2(2, 0));
137
- float l1 = fetchDepth(p - ivec2(1, 0));
138
- float r1 = fetchDepth(p + ivec2(1, 0));
139
- float r2 = fetchDepth(p + ivec2(2, 0));
140
- float b2 = fetchDepth(p - ivec2(0, 2));
141
- float b1 = fetchDepth(p - ivec2(0, 1));
142
- float t1 = fetchDepth(p + ivec2(0, 1));
143
- float t2 = fetchDepth(p + ivec2(0, 2));
144
- float dl = abs((2.0 * l1 - l2) - c0);
145
- float dr = abs((2.0 * r1 - r2) - c0);
146
- float db = abs((2.0 * b1 - b2) - c0);
147
- float dt = abs((2.0 * t1 - t2) - c0);
148
- vec3 ce = getViewPosition(uv, c0).xyz;
149
- vec3 dpdx = (dl < dr) ? ce - getViewPosition((uv - vec2(1.0 / size.x, 0.0)), l1).xyz
150
- : -ce + getViewPosition((uv + vec2(1.0 / size.x, 0.0)), r1).xyz;
151
- vec3 dpdy = (db < dt) ? ce - getViewPosition((uv - vec2(0.0, 1.0 / size.y)), b1).xyz
152
- : -ce + getViewPosition((uv + vec2(0.0, 1.0 / size.y)), t1).xyz;
153
- return normalize(cross(dpdx, dpdy));
133
+ vec2 size = vec2(textureSize(tDepth, 0));
134
+ ivec2 p = ivec2(uv * size);
135
+ float c0 = fetchDepth(p);
136
+ float l2 = fetchDepth(p - ivec2(2, 0));
137
+ float l1 = fetchDepth(p - ivec2(1, 0));
138
+ float r1 = fetchDepth(p + ivec2(1, 0));
139
+ float r2 = fetchDepth(p + ivec2(2, 0));
140
+ float b2 = fetchDepth(p - ivec2(0, 2));
141
+ float b1 = fetchDepth(p - ivec2(0, 1));
142
+ float t1 = fetchDepth(p + ivec2(0, 1));
143
+ float t2 = fetchDepth(p + ivec2(0, 2));
144
+ float dl = abs((2.0 * l1 - l2) - c0);
145
+ float dr = abs((2.0 * r1 - r2) - c0);
146
+ float db = abs((2.0 * b1 - b2) - c0);
147
+ float dt = abs((2.0 * t1 - t2) - c0);
148
+ vec3 ce = getViewPosition(uv, c0).xyz;
149
+ vec3 dpdx = (dl < dr) ? ce - getViewPosition((uv - vec2(1.0 / size.x, 0.0)), l1).xyz : -ce + getViewPosition((uv + vec2(1.0 / size.x, 0.0)), r1).xyz;
150
+ vec3 dpdy = (db < dt) ? ce - getViewPosition((uv - vec2(0.0, 1.0 / size.y)), b1).xyz : -ce + getViewPosition((uv + vec2(0.0, 1.0 / size.y)), t1).xyz;
151
+ return normalize(cross(dpdx, dpdy));
154
152
}
155
153
156
154
vec3 getViewNormal(const vec2 uv) {
@@ -182,14 +180,14 @@ const GTAOShader = {
182
180
float radiusToUse = radius;
183
181
float distanceFalloffToUse = thickness;
184
182
#if SCREEN_SPACE_RADIUS == 1
185
- float radiusScale = getViewPosition(vec2(0.5 + float(SCREEN_SPACE_RADIUS_SCALE) / resolution.x, 0.0), depth).x;
183
+ float radiusScale = getViewPosition(vec2(0.5 + float(SCREEN_SPACE_RADIUS_SCALE) / resolution.x, 0.0), depth).x;
186
184
radiusToUse *= radiusScale;
187
185
distanceFalloffToUse *= radiusScale;
188
186
#endif
189
187
190
188
#if SCENE_CLIP_BOX == 1
191
189
vec3 worldPos = (cameraWorldMatrix * vec4(viewPos, 1.0)).xyz;
192
- float boxDistance = length(max(vec3(0.0), max(sceneBoxMin - worldPos, worldPos - sceneBoxMax)));
190
+ float boxDistance = length(max(vec3(0.0), max(sceneBoxMin - worldPos, worldPos - sceneBoxMax)));
193
191
if (boxDistance > radiusToUse) {
194
192
discard;
195
193
return;
@@ -345,6 +343,7 @@ function generateMagicSquareNoise( size = 5 ) {
345
343
const magicSquare = generateMagicSquare ( noiseSize ) ;
346
344
const noiseSquareSize = magicSquare . length ;
347
345
const data = new Uint8Array ( noiseSquareSize * 4 ) ;
346
+
348
347
for ( let inx = 0 ; inx < noiseSquareSize ; ++ inx ) {
349
348
350
349
const iAng = magicSquare [ inx ] ;
@@ -365,21 +364,22 @@ function generateMagicSquareNoise( size = 5 ) {
365
364
noiseTexture . wrapS = RepeatWrapping ;
366
365
noiseTexture . wrapT = RepeatWrapping ;
367
366
noiseTexture . needsUpdate = true ;
367
+
368
368
return noiseTexture ;
369
369
370
370
}
371
371
372
372
function generateMagicSquare ( size ) {
373
373
374
- const noiseSize =
375
- Math . floor ( size ) % 2 === 0 ? Math . floor ( size ) + 1 : Math . floor ( size ) ;
374
+ const noiseSize = Math . floor ( size ) % 2 === 0 ? Math . floor ( size ) + 1 : Math . floor ( size ) ;
376
375
const noiseSquareSize = noiseSize * noiseSize ;
377
376
const magicSquare = Array ( noiseSquareSize ) . fill ( 0 ) ;
378
377
let i = Math . floor ( noiseSize / 2 ) ;
379
378
let j = noiseSize - 1 ;
379
+
380
380
for ( let num = 1 ; num <= noiseSquareSize ; ) {
381
381
382
- if ( i === - 1 && j === noiseSize ) {
382
+ if ( i === - 1 && j === noiseSize ) {
383
383
384
384
j = noiseSize - 2 ;
385
385
i = 0 ;
@@ -388,19 +388,19 @@ function generateMagicSquare( size ) {
388
388
389
389
if ( j === noiseSize ) {
390
390
391
- j = 0 ;
391
+ j = 0 ;
392
392
393
393
}
394
394
395
395
if ( i < 0 ) {
396
396
397
- i = noiseSize - 1 ;
397
+ i = noiseSize - 1 ;
398
398
399
399
}
400
400
401
401
}
402
402
403
- if ( magicSquare [ i * noiseSize + j ] !== 0 ) {
403
+ if ( magicSquare [ i * noiseSize + j ] !== 0 ) {
404
404
405
405
j -= 2 ;
406
406
i ++ ;
@@ -412,8 +412,8 @@ function generateMagicSquare( size ) {
412
412
413
413
}
414
414
415
- j ++ ;
416
- i -- ;
415
+ j ++ ;
416
+ i -- ;
417
417
418
418
}
419
419
0 commit comments