Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何在deckgl的trips layer中使用图像纹理? #21

Open
Diazhao opened this issue Feb 9, 2021 · 0 comments
Open

如何在deckgl的trips layer中使用图像纹理? #21

Diazhao opened this issue Feb 9, 2021 · 0 comments

Comments

@Diazhao
Copy link
Owner

Diazhao commented Feb 9, 2021

vv. how to use image texture in deck gl`s trips layer?
回到正题。

问题的重点有两个,

  1. 如何在deckgl中使用图像纹理?
  2. 真实坐标与纹理坐标之间的映射?

好的,我们来看下

第一个问题。

在deck gl中使用纹理,需要结合luma.gl的Texture2D类,通过这个类可以将加载完成的图像转换到deck gl可以使用的纹理数据类型(加载纹理用的图像不能跨域,而且需要加载完成之后才可以用于初始化这个类),代码如下所示

import { Texture2D } from '@luma.gl/core'

createTexture(gl, opt) {
    const textureOptions = Object.assign(
      {
        dataFormat: gl.RGBA,
        type: gl.FLOAT,
        parameters: {
          [gl.TEXTURE_MAG_FILTER]: gl.NEAREST,
          [gl.TEXTURE_MIN_FILTER]: gl.NEAREST,
          [gl.TEXTURE_WRAP_S]: gl.CLAMP_TO_EDGE,
          [gl.TEXTURE_WRAP_T]: gl.CLAMP_TO_EDGE
        },
        pixelStore: {[gl.UNPACK_FLIP_Y_WEBGL]: true}
      },
      opt
    );

    return new Texture2D(gl, textureOptions);
  }
第二个问题,敲黑板,重点

纹理坐标与真实坐标的对应关系。
首先看到,deckgl绘制trips layer的原理,是将我们的轨迹数据按照时间序列化。根据设定的一个长度展示对应时间段内的数据。我们需要做的就是将展示的这一部分数据与加载的纹理对应起来。需要新建一个类,重写原来trips layer的getShader方法,废话不多说,直接看下代码.

getShaders () {
    const shaders = super.getShaders()
    shaders.inject = {
      'vs:#decl': `\
        uniform float trailLength;
        attribute float instanceTimestamps;
        attribute float instanceNextTimestamps;
        uniform float currentTime;
        varying float vTime;
       // 新增加一个varying变量,记录纹理坐标
        varying vec2 vCoord;
      `,
      // Timestamp of the vertex
      'vs:#main-end': `\
        gl_PointSize = 20.0;
        vTime = instanceTimestamps + (instanceNextTimestamps - instanceTimestamps) * vPathPosition.y / vPathLength;
        // position是原trips layer中记录纹理坐标的一个变量,我们把它传到片元着色器中
        vCoord = positions;
      `,
      'fs:#decl': `\
        uniform float trailLength;
        uniform float currentTime;
        uniform sampler2D utexture;
        varying float vTime;
        // 接收顶点着色器传过来的变量
        varying vec2 vCoord;
      `,
      // Drop the segments outside of the time window
      'fs:#main-start': `\
        if(vTime > currentTime || vTime < currentTime - trailLength) {
          discard;
        }
      `,
      'fs:#main-end': `\
        if(vTime > currentTime || vTime < currentTime - trailLength) {
          discard;
        }
        // 计算当前计算的顶点位于轨迹的什么位置
        float a = 1.0 - (currentTime - vTime) / trailLength;
        // 使用vCoord判断当前顶点是轨迹的左边还是右边, 以及当前顶点在轨迹中的位置
        vec2 tCoord = vec2(vCoord.y * 0.5 + 0.5, a);
        // 指定对应的纹理坐标
        gl_FragColor = texture2D(utexture, tCoord);
      `,
      // Fade the color (currentTime - 100%, end of trail - 0%)
      'fs:DECKGL_FILTER_COLOR': 'color.a *= 1.0 - (currentTime - vTime) / trailLength;'
    }
    return shaders
  }
最后,我们需要在绘制的时候,把第一步创建的纹理传到着色器中即可。
draw (opts) {
  if(!_texture) return
  this.state.model.setUniforms({
    utexture: _texture
  });
}

目前遗留的问题

现阶段在轨迹原有的两个记录交接的地方,也就是拐弯的时候,会出现毛边儿的现象,应该是顶点计算的时候的问题。还需要解决。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant