UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

70 lines (58 loc) 4.63 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{floor as e,set as t,sub as o,scale as i,normalize as a,dot as r,lerp as n}from"../core/libs/gl-matrix-2/math/vec3.js";import{create as s,fromValues as d}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{Float3BindUniform as c}from"../views/3d/webgl-engine/core/shaderModules/Float3BindUniform.js";import{Float3PassUniform as l}from"../views/3d/webgl-engine/core/shaderModules/Float3PassUniform.js";import{FloatPassUniform as m}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{glsl as p}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Matrix4BindUniform as v}from"../views/3d/webgl-engine/core/shaderModules/Matrix4BindUniform.js";import{ShaderBuilder as f}from"../views/webgl/ShaderBuilder.js";function u(e){const t=new f;return t.attributes.add("position","vec3"),t.attributes.add("instanceFeatureAttribute","float"),t.vertex.uniforms.add(new c("cameraPosition",e=>e.camera.eye),new l("offset",(e,t)=>h(e,t)),new m("width",e=>e.width),new m("time",e=>e.time),new v("proj",e=>e.camera.projectionMatrix),new v("view",e=>e.camera.viewMatrix)),t.varyings.add("vUv","vec2"),t.vertex.code.add(p`vec3 hash31(float p){ vec3 p3 = fract(vec3(p) * vec3(0.1031, 0.1030, 0.0973)); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.xxy + p3.yzz) * p3.zyx); } float hash11(float p){ p = fract(p * 0.1031); p *= p + 33.33; p *= p + p; return fract(p); } vec3 rotateVectorByQuaternion(vec3 v, vec4 q){ return 2.0 * cross(q.xyz, v * q.w + cross(q.xyz, v)) + v; }`),t.vertex.main.add(p` vUv = position.xz; vec3 rand = hash31(instanceFeatureAttribute); // Set random position for all particles // The hash function space is not high resolution so offset particles by an additional random value // This creates grids of 1000 particles which are shifted by random hundredths of the tile width // overlaying multiple identical but offset grids vec3 randomPosition = 2.0 * (rand + (0.01 + 0.01 * rand) * floor(0.001 * instanceFeatureAttribute)) - 1.0; // Random orientation of rain drops float angle = 3.1415 * hash11(instanceFeatureAttribute); vec3 up = vec3(0, 0, 1); // Gravity and wind direction vec3 direction = normalize(cameraPosition); vec3 tangent = normalize(cross(direction, up)); // Gravity vec3 animatedPos = randomPosition + direction * -time; // Rain particles fall straight down and are randomly oriented // Snow particles have random sinusoid trajectories and are rotated to face the camera ${0===e.type?p` // Random rotation for particle vec3 rotationAxis = up; vec4 quat = vec4(rotationAxis * sin(angle), cos(angle)); vec3 transformedPos = rotateVectorByQuaternion(vec3(0.2, 0.2, 4.0) * (position - vec3(0.5, 0.0, 0.5)), quat); // Rotate particle to planetary position rotationAxis = tangent; angle = 0.5 * -acos(dot(direction, up)); quat = vec4(rotationAxis * sin(angle), cos(angle)); transformedPos = rotateVectorByQuaternion(transformedPos, quat); vec4 pos = mat4(mat3(view)) * vec4(transformedPos + (mod(width * animatedPos - offset, width) - 0.5 * width), 1.0); gl_Position = proj * pos; `:p` vec3 rotationAxis = direction; vec4 quat = vec4(rotationAxis * sin(angle), cos(angle)); tangent = rotateVectorByQuaternion(tangent, quat); // Random sinusoid from friction animatedPos += tangent * 0.25 * sin(dot(animatedPos, direction)); vec4 pos = mat4(mat3(view)) * vec4((mod(width * animatedPos - offset, width) - 0.5 * width), 1.0); gl_Position = proj * (0.5 * vec4(position.xzy, 0.0) + pos); `} `),t.fragment.uniforms.add(new m("opacity",e=>e.opacity),new c("particleColor",t=>g(t,e))),t.fragment.main.add(p` float d = length(vUv - vec2(0.5)); ${0===e.type?p`d = 0.35 * smoothstep(0.5, 0.0, d);`:p`d = smoothstep(0.5, 0.1, d);`} fragColor = opacity * vec4(particleColor * d, d); `),t}function h(a,r){const n=r.camera.eye,s=.5*a.width,d=1/a.width,c=e(w,t(w,(n[0]+s)*d,(n[1]+s)*d,(n[2]+s)*d));return o(c,n,i(c,c,a.width))}function g(e,t){const o=0===t.type?b:x,s=i(w,o,P),d=e.camera.eye;a(y,d);const c=Math.max(0,r(y,e.lighting.mainLight.direction));return n(s,s,o,c)}const w=s(),y=s(),x=d(1,1,1),b=d(.85,.85,.85),P=.7,j=Object.freeze(Object.defineProperty({__proto__:null,build:u},Symbol.toStringTag,{value:"Module"}));export{j as P,u as b};