@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
73 lines (61 loc) • 4.87 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{J as e,i as t,a as o,g as i,n as a,e as r,m as n}from"./vec32.js";import{create as s,fromValues as d}from"../core/libs/gl-matrix-2/factories/vec3f64.js";import{PrecipitationType as c}from"../views/3d/environment/PrecipitationTechniqueConfiguration.js";import{Float3BindUniform as m}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 p}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{glsl as v}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{Matrix4BindUniform as f}from"../views/3d/webgl-engine/core/shaderModules/Matrix4BindUniform.js";import{VertexAttribute as u}from"../views/3d/webgl-engine/lib/VertexAttribute.js";import{ShaderBuilder as h}from"../views/webgl/ShaderBuilder.js";function g(e){const t=new h;return t.attributes.add(u.POSITION,"vec3"),t.attributes.add(u.INSTANCEFEATUREATTRIBUTE,"float"),t.vertex.uniforms.add(new m("cameraPosition",(e=>e.camera.eye)),new l("offset",((e,t)=>w(e,t))),new p("width",(e=>e.width)),new p("time",(e=>e.time)),new f("proj",(e=>e.camera.projectionMatrix)),new f("view",(e=>e.camera.viewMatrix))),t.varyings.add("vUv","vec2"),t.vertex.code.add(v`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(v`
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
${e.type===c.Rain?v`
// 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;
`:v`
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 p("opacity",(e=>e.opacity)),new m("particleColor",(t=>y(t,e)))),t.fragment.main.add(v`
float d = length(vUv - vec2(0.5));
${e.type===c.Rain?v`d = 0.35 * smoothstep(0.5, 0.0, d);`:v`d = smoothstep(0.5, 0.1, d);`}
fragColor = opacity * vec4(particleColor * d, d);
`),t}function w(a,r){const n=r.camera.eye,s=.5*a.width,d=1/a.width,c=e(x,t(x,(n[0]+s)*d,(n[1]+s)*d,(n[2]+s)*d));return o(c,n,i(c,c,a.width))}function y(e,t){const o=t.type===c.Rain?j:P,s=i(x,o,A),d=e.camera.eye;a(b,d);const m=Math.max(0,r(b,e.lighting.mainLight.direction));return n(s,s,o,m)}const x=s(),b=s(),P=d(1,1,1),j=d(.85,.85,.85),A=.7,q=Object.freeze(Object.defineProperty({__proto__:null,build:g},Symbol.toStringTag,{value:"Module"}));export{q as P,g as b};