You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
4.6 KiB
89 lines
4.6 KiB
// All material copyright Esri, All Rights Reserved, unless otherwise specified. |
|
// See https://js.arcgis.com/4.30/esri/copyright.txt for details. |
|
//>>built |
|
define("exports ../core/libs/gl-matrix-2/math/vec2 ../core/libs/gl-matrix-2/factories/vec2f64 ../views/3d/webgl-engine/core/shaderLibrary/ScreenSpacePass.glsl ../views/3d/webgl-engine/core/shaderLibrary/output/ReadDepth.glsl ../views/3d/webgl-engine/core/shaderLibrary/util/CameraSpace.glsl ../views/3d/webgl-engine/core/shaderModules/Float2PassUniform ../views/3d/webgl-engine/core/shaderModules/FloatPassUniform ../views/3d/webgl-engine/core/shaderModules/interfaces ../views/3d/webgl-engine/core/shaderModules/ShaderBuilder ../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform".split(" "), |
|
function(f,m,g,r,t,u,n,h,d,v,k){function p(){const b=new v.ShaderBuilder,e=b.fragment;b.include(r.ScreenSpacePass);b.include(u.CameraSpace);e.include(t.ReadDepth);e.uniforms.add(new h.FloatPassUniform("radius",(a,c)=>l(c.camera))).code.add(d.glsl`vec3 sphere[16] = vec3[16]( |
|
vec3(0.186937, 0.0, 0.0), |
|
vec3(0.700542, 0.0, 0.0), |
|
vec3(-0.864858, -0.481795, -0.111713), |
|
vec3(-0.624773, 0.102853, -0.730153), |
|
vec3(-0.387172, 0.260319, 0.007229), |
|
vec3(-0.222367, -0.642631, -0.707697), |
|
vec3(-0.01336, -0.014956, 0.169662), |
|
vec3(0.122575, 0.1544, -0.456944), |
|
vec3(-0.177141, 0.85997, -0.42346), |
|
vec3(-0.131631, 0.814545, 0.524355), |
|
vec3(-0.779469, 0.007991, 0.624833), |
|
vec3(0.308092, 0.209288,0.35969), |
|
vec3(0.359331, -0.184533, -0.377458), |
|
vec3(0.192633, -0.482999, -0.065284), |
|
vec3(0.233538, 0.293706, -0.055139), |
|
vec3(0.417709, -0.386701, 0.442449) |
|
); |
|
float fallOffFunction(float vv, float vn, float bias) { |
|
float f = max(radius * radius - vv, 0.0); |
|
return f * f * f * max(vn - bias, 0.0); |
|
}`);e.code.add(d.glsl`float aoValueFromPositionsAndNormal(vec3 C, vec3 n_C, vec3 Q) { |
|
vec3 v = Q - C; |
|
float vv = dot(v, v); |
|
float vn = dot(normalize(v), n_C); |
|
return fallOffFunction(vv, vn, 0.1); |
|
}`);e.uniforms.add(new k.Texture2DPassUniform("normalMap",a=>a.normalTexture),new k.Texture2DPassUniform("depthMap",a=>a.depthTexture),new h.FloatPassUniform("projScale",a=>a.projScale),new k.Texture2DPassUniform("rnm",a=>a.noiseTexture),new n.Float2PassUniform("rnmScale",(a,c)=>m.set(q,c.camera.fullWidth/a.noiseTexture.descriptor.width,c.camera.fullHeight/a.noiseTexture.descriptor.height)),new h.FloatPassUniform("intensity",a=>a.intensity),new n.Float2PassUniform("screenSize",(a,c)=>m.set(q,c.camera.fullWidth, |
|
c.camera.fullHeight)));b.outputs.add("fragOcclusion","float");e.code.add(d.glsl` |
|
void main(void) { |
|
float depth = depthFromTexture(depthMap, uv); |
|
|
|
// Early out if depth is out of range, such as in the sky |
|
if (depth >= 1.0 || depth <= 0.0) { |
|
fragOcclusion = 1.0; |
|
return; |
|
} |
|
|
|
// get the normal of current fragment |
|
vec4 norm4 = texture(normalMap, uv); |
|
if(norm4.a != 1.0) { |
|
fragOcclusion = 1.0; |
|
return; |
|
} |
|
vec3 norm = vec3(-1.0) + 2.0 * norm4.xyz; |
|
|
|
float currentPixelDepth = linearizeDepth(depth); |
|
vec3 currentPixelPos = reconstructPosition(gl_FragCoord.xy, currentPixelDepth); |
|
|
|
float sum = 0.0; |
|
vec3 tapPixelPos; |
|
|
|
vec3 fres = normalize(2.0 * texture(rnm, uv * rnmScale).xyz - 1.0); |
|
|
|
// note: the factor 2.0 should not be necessary, but makes ssao much nicer. |
|
// bug or deviation from CE somewhere else? |
|
float ps = projScale / (2.0 * currentPixelPos.z * zScale.x + zScale.y); |
|
|
|
for(int i = 0; i < ${d.glsl.int(16)}; ++i) { |
|
vec2 unitOffset = reflect(sphere[i], fres).xy; |
|
vec2 offset = vec2(-unitOffset * radius * ps); |
|
|
|
// don't use current or very nearby samples |
|
if( abs(offset.x) < 2.0 || abs(offset.y) < 2.0){ |
|
continue; |
|
} |
|
|
|
vec2 tc = vec2(gl_FragCoord.xy + offset); |
|
if (tc.x < 0.0 || tc.y < 0.0 || tc.x > screenSize.x || tc.y > screenSize.y) continue; |
|
vec2 tcTap = tc / screenSize; |
|
float occluderFragmentDepth = linearDepthFromTexture(depthMap, tcTap); |
|
|
|
tapPixelPos = reconstructPosition(tc, occluderFragmentDepth); |
|
|
|
sum += aoValueFromPositionsAndNormal(currentPixelPos, norm, tapPixelPos); |
|
} |
|
|
|
// output the result |
|
float A = max(1.0 - sum * intensity / float(${d.glsl.int(16)}), 0.0); |
|
|
|
// Anti-tone map to reduce contrast and drag dark region farther: (x^0.2 + 1.2 * x^4) / 2.2 |
|
A = (pow(A, 0.2) + 1.2 * A*A*A*A) / 2.2; |
|
|
|
fragOcclusion = A; |
|
} |
|
`);return b}function l(b){return Math.max(10,20*b.computeScreenPixelSizeAtDist(Math.abs(4*b.relativeElevation)))}const q=g.create();g=Object.freeze(Object.defineProperty({__proto__:null,build:p,getRadius:l},Symbol.toStringTag,{value:"Module"}));f.SSAO=g;f.build=p;f.getRadius=l}); |