• maptalks 开发GIS地图(30)maptalks.three.23- custom-electricShield


    1. 电子罩栏,这个效果很不错了。可是用在什么地方比较合适呢?

    2. 定义扩展对象类

     1 class ElectricShield extends maptalks.BaseObject {
     2             constructor(coordinate, options, material, layer) {
     3                 options = maptalks.Util.extend({}, OPTIONS, options, { layer, coordinate });
     4                 super();
     5                 //Initialize internal configuration
     6                 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135
     7                 this._initOptions(options);
     8                 const { altitude, radius } = options;
     9                 //generate geometry
    10                 const r = layer.distanceToVector3(radius, radius).x;
    11                 const geometry = new THREE.SphereBufferGeometry(r, 50, 50, 0, Math.PI * 2);
    12 
    13                 //Initialize internal object3d
    14                 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L140
    15                 // this._createMesh(geometry, material);
    16                 this._createGroup();
    17                 const mesh = new THREE.Mesh(geometry, material);
    18                 this.getObject3d().add(mesh);
    19                 //set object3d position
    20                 const z = layer.distanceToVector3(altitude, altitude).x;
    21                 const position = layer.coordinateToVector3(coordinate, z);
    22                 this.getObject3d().position.copy(position);
    23                 this.getObject3d().rotation.x = Math.PI / 2;
    24             }
    25 
    26             _animation() {
    27                 const ball = this.getObject3d().children[0];
    28                 const speed = this.getOptions().speed;
    29                 ball.material.uniforms.time.value += speed;
    30             }
    31         }

    3. 电子罩栏的材质,其中使用了 ShaderMaterial

      1 function getMaterial() {
      2             var ElectricShield = {
      3                 uniforms: {
      4                 time: {
      5                     type: "f",
      6                     value: 0
      7                 },
      8                 color: {
      9                     type: "c",
     10                     value: new THREE.Color("#9999FF")
     11                 },
     12                 opacity: {
     13                     type: "f",
     14                     value: 1
     15                 }
     16                 },
     17                 vertexShaderSource: "
      precision lowp float;
      precision lowp int;
      "
     18                 .concat(
     19                     THREE.ShaderChunk.fog_pars_vertex,
     20                     "
      varying vec2 vUv;
      void main() {
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        "
     21                 )
     22                 .concat(THREE.ShaderChunk.fog_vertex, "
      }
    "),
     23                 fragmentShaderSource: `
     24                 #if __VERSION__ == 100
     25                  #extension GL_OES_standard_derivatives : enable
     26                 #endif
     27                 uniform vec3 color;
     28                 uniform float opacity;
     29                 uniform float time;
     30                 varying vec2 vUv;
     31                 #define pi 3.1415926535
     32                 #define PI2RAD 0.01745329252
     33                 #define TWO_PI (2. * PI)
     34                 float rands(float p){
     35                     return fract(sin(p) * 10000.0);
     36                 }
     37                 float noise(vec2 p){
     38                     float t = time / 20000.0;
     39                     if(t > 1.0) t -= floor(t);
     40                     return rands(p.x * 14. + p.y * sin(t) * 0.5);
     41                 }
     42                 vec2 sw(vec2 p){
     43                     return vec2(floor(p.x), floor(p.y));
     44                 }
     45                 vec2 se(vec2 p){
     46                     return vec2(ceil(p.x), floor(p.y));
     47                 }
     48                 vec2 nw(vec2 p){
     49                     return vec2(floor(p.x), ceil(p.y));
     50                 }
     51                 vec2 ne(vec2 p){
     52                     return vec2(ceil(p.x), ceil(p.y));
     53                 }
     54                 float smoothNoise(vec2 p){
     55                     vec2 inter = smoothstep(0.0, 1.0, fract(p));
     56                     float s = mix(noise(sw(p)), noise(se(p)), inter.x);
     57                     float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
     58                     return mix(s, n, inter.y);
     59                 }
     60                 float fbm(vec2 p){
     61                     float z = 2.0;
     62                     float rz = 0.0;
     63                     vec2 bp = p;
     64                     for(float i = 1.0; i < 6.0; i++){
     65                     rz += abs((smoothNoise(p) - 0.5)* 2.0) / z;
     66                     z *= 2.0;
     67                     p *= 2.0;
     68                     }
     69                     return rz;
     70                 }
     71                 void main() {
     72                     vec2 uv = vUv;
     73                     vec2 uv2 = vUv;
     74                     if (uv.y < 0.5) {
     75                     discard;
     76                     }
     77                     uv *= 4.;
     78                     float rz = fbm(uv);
     79                     uv /= exp(mod(time * 2.0, pi));
     80                     rz *= pow(15., 0.9);
     81                     gl_FragColor = mix(vec4(color, opacity) / rz, vec4(color, 0.1), 0.2);
     82                     if (uv2.x < 0.05) {
     83                     gl_FragColor = mix(vec4(color, 0.1), gl_FragColor, uv2.x / 0.05);
     84                     }
     85                     if (uv2.x > 0.95){
     86                     gl_FragColor = mix(gl_FragColor, vec4(color, 0.1), (uv2.x - 0.95) / 0.05);
     87                     }
     88                 }`
     89             };
     90             let material = new THREE.ShaderMaterial({
     91                 uniforms: ElectricShield.uniforms,
     92                 defaultAttributeValues: {},
     93                 vertexShader: ElectricShield.vertexShaderSource,
     94                 fragmentShader: ElectricShield.fragmentShaderSource,
     95                 blending: THREE.AdditiveBlending,
     96                 depthWrite: !1,
     97                 depthTest: !0,
     98                 side: THREE.DoubleSide,
     99                 transparent: !0
    100             });
    101             return material;
    102         }

    4. 添加电子罩栏

    1         var ballElectric, material;
    2         function addElectricShield() {
    3             material = getMaterial();
    4             ballElectric = new ElectricShield(map.getCenter(), { radius: 500 }, material, threeLayer)
    5             threeLayer.addMesh(ballElectric);
    6             initGui();
    7             animation();
    8         }

    5. 页面显示

    6. 源码地址

    https://github.com/WhatGIS/maptalkMap/tree/main/threelayer/demo

  • 相关阅读:
    mac的端口被占用
    php中的运算符、控制结构
    文档模式影响浏览器的渲染
    ubuntu 命令 tips 来自于 ubuntu中文论坛
    用好 Emacs 中的 register
    [转载] Rsync命令参数详解
    使用 python 遍历目录下的文件
    灵活的左移位( << )操作
    使用 iperf 测试两台机器间的最大带宽
    Emacs server 新启动方式 (仅在emacs daemon未启动时才启动daemon)
  • 原文地址:https://www.cnblogs.com/googlegis/p/14735545.html
Copyright © 2020-2023  润新知