Cesium中自定义材质(以飞线材质为例)

1、entity自定义材质

        entity材质类型为Cesium.MaterialProperty。自定义材质实例如下,例子为实现飞线材质

import * as Cesium from 'cesium'
import gsap from 'gsap'
export default class PolylineTrailMaterialProperty {
  params: {
    uTime: number
  }
  name: string

  definitionChanged = new Cesium.Event()
  isConstant = false

  constructor(name: string) {
    this.name = name
    this.params = {
      uTime: 0
    }
    ;(Cesium.Material as any)._materialCache.addMaterial(
      'PolylineTrailMaterial',
      {
        fabric: {
          type: 'PolylineTrailMaterial',
          uniforms: {
              uTime:this.params.uTime
            },
          source: `
        czm_material czm_getMaterial(czm_materialInput materialInput)
        {
          // 生成默认的基础材质
          czm_material material = czm_getDefaultMaterial(materialInput);
          vec2 st = materialInput.st;
          // 定义动画持续时间,从0到1
          float durationTime = 10.0;
          // 获取当前帧数,fract(x) 返回x的小数部分
          float time = fract(czm_frameNumber / (60.0 * durationTime));
          time = time * (1.0 + 0.1);
          // 平滑过度函数
          // smoothstep(edge0,edge1,val)
          float alpha = smoothstep(time - 0.1,time,st.s) * step(-time,-st.s);
          material.alpha = alpha;
          material.diffuse = vec3(1.0,1.0,1.0);
          return material;
        }
        `
        }
      }
    )
    this.animate()
  }
  getType(time?: Cesium.JulianDate) {
    return 'PolylineTrailMaterial'
  }
  getValue(time: Cesium.JulianDate, result: { [key: string]: number }) {
    result.uTime = this.params.uTime
    return result
  }
  equals(other: Cesium.Property): boolean {
    // 判断两个材质是否相等
    return (
      other instanceof PolylineTrailMaterialProperty && this.name === other.name
    )
  }
  animate() {
    gsap.to(this.params, {
      uTime: 1,
      duration: 1,
      repeat: -1,
      yoyo: true
    })
  }
}

2、primitive的创建需要分为geometry、instance、appearance、material、primitive五步,material在appearance的option中,为Cesium.Material类型,他的自定义方式与上述类似

let material = new Cesium.Material({
    fabric:{
        uniforms:{
        },
        source:{`
            czm_material czm_getMaterial(czm_materialInput materialInput){
                czm_material material = czm_getDefaultMaterial(materialInput);
                material.diffuse=vec3(1.0,0.0,0.0);
                return material;
            }
        `}
    }
})

 上述源码存在于material.shaderSource中,在片元着色器中调用。

appearance._fragmentShaderSource : 片元着色器

appearance._vertexShaderSource : 顶点着色器

3、一些注意点

        czm_frameNumber : 当前帧数

        czm_materialInput:作为每个材质的czm_getMaterial函数的输入。

        materialInput.st:二位纹理坐标,s从下至上,t从左至右,左下角(0,0),右上角(1,1)

        glsl中一些常用函数:

                smoothstep(t1,t2,val) : 生成0到1的平滑过渡值,它也叫平滑阶梯函数 ,x在 t1 到 t2 值的范围内变化曲线由缓到快再到缓的过程。

                step(x,a) :  如果a小于x就是0 否则 返回1。

                fract(x) : 返回x的小数部分 

                clamp(x,min,max) : 将随机变化的数值限制在一个给定的区间[min, max]内,也就是第一个和第二个比 选出大的temp,然后temp和第三个比,选出小的。

4、用纹理图实现轨迹飞线材质

import * as Cesium from 'cesium'
export default class SpritelineMaterialProperty {
  name: string
  img: string

  definitionChanged = new Cesium.Event()
  isConstant = false

  constructor(name: string = 'spriteline1') {
    this.name = name
    this.img = '/api/textures/spriteline1.png'
    ;(Cesium.Material as any)._materialCache.addMaterial(
      'SpritelineMaterialProperty',
      {
        fabric: {
          type: 'SpritelineMaterialProperty',
          uniforms: {
            img: this.img
          },
          source: `
        czm_material czm_getMaterial(czm_materialInput materialInput)
        {
          // 生成默认的基础材质
          czm_material material = czm_getDefaultMaterial(materialInput);
          vec2 st = materialInput.st;
          // 定义动画持续时间,从0到1
          float durationTime = 2.0;
          // 获取当前帧数,fract(x) 返回x的小数部分
          float time = fract(czm_frameNumber / (60.0 * durationTime));
          // 根据uv采样颜色
          vec4 color = texture2D(img,vec2(fract(st.s - time),st.t));
          material.alpha = color.a;
          material.diffuse = color.rgb;
          return material;
        }
        `
        }
      }
    )
  }
  getType(time?: Cesium.JulianDate) {
    return 'SpritelineMaterialProperty'
  }
  getValue(time: Cesium.JulianDate, result: { [key: string]: number }) {
    return result
  }
  equals(other: Cesium.Property): boolean {
    // 判断两个材质是否相等
    return (
      other instanceof SpritelineMaterialProperty && this.name === other.name
    )
  }
}

vec4 texture2D(sampler2D sampler, vec2 coord) :第一个参数代表图片纹理,第二个参数代表纹理坐标点,通过GLSL的内建函数texture2D来获取对应位置纹理的颜色RGBA值               

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值