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

支持 Point / Line / Polygon / Heatmap 在 WebGPU 下的渲染 #2225

Merged
merged 24 commits into from
Jan 9, 2024

Conversation

xiaoiver
Copy link
Contributor

@xiaoiver xiaoiver commented Dec 26, 2023

[English Template / 英文模板]

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复
  • 站点、文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • TypeScript 定义更新
  • 包体积优化
  • 性能优化
  • 功能增强
  • 国际化改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 工作流程
  • 版本更新
  • 其他改动(是关于什么的改动?)

🔗 相关 Issue

验证 WebGPU 渲染能力。新增示例:

  • point fill / image / column / text
  • line normal / arc
  • polygon extrude / fill / texture
  • heatmap grid / grid 3d / normal

控制台的 warning 可以忽略:

1 warning(s) generated while compiling the shader:
:442:5 warning: code is unreachable
    let _e79 = global_2.u_FocalDistance;
    ^^^^^^^^

不过也能看出 project_float_meter 这个函数确实有执行不到的代码,可以优化一下:

截屏2023-12-27 上午10 07 49

💡 需求背景和解决方案

启用 WebGPU 渲染器方式如下:

const scene = new Scene({
  renderer: 'device', // 选择 device 渲染器
  enableWebGPU: true, // 开启 WebGPU
  shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', // 传入 WASM
});

该 WASM 的主要作用是将 GLSL 440 转成 WebGPU 需要的 WGSL。

局限性 & 差异点

WebGPU 和 WebGL 存在不少差异

gl_PointSize 不支持

gpuweb/gpuweb#1190

WGSL 不支持 gl_PointSize wgsl::write_string Unsupported builtin PointSize 因此 point billboard / normal 没法运行

textureSample 只能写在确定分支中

例如 polygon water 的例子中如下写法会报错:

if (v1 > 1.0) { // non-uniform var
  vec3 c1 = texture(SAMPLER_2D(u_texture), p.xz / 30.).xyz;
}
Tint WGSL reader failure: :245:25 error: 'textureSample' must only be called from uniform control flow

解决办法是在顶部添加:https://www.w3.org/TR/WGSL/#example-70cf6bac

diagnostic(off,derivative_uniformity);

可以在 Model 中添加配置,开启后在编译成 WGSL 之后添加。

flip Y

在热力图示例中,需要使用 framebuffer 中的纹理,此时需要根据 VIEWPORT_ORIGIN_TL 判断是否翻转 Y 轴。该变量由 @antv/g-device-api 添加,WebGL 1/2 下不写入,WebGPU 下才写入:

gpuweb/gpuweb#416

v_texCoord = a_Uv;
#ifdef VIEWPORT_ORIGIN_TL
  v_texCoord.y = 1.0 - v_texCoord.y;
#endif

Vertex buffer 数量限制

最多 8 个,超出会报错:

exceeds the maximum number of vertex buffers (8).

因此类似 line 中的写法需要合并,减少数目:

// before
layout(location = 13) in vec3 a_Normal;
layout(location = 14) in float a_Total_Distance;

// after
layout(location = 13) in vec4 a_Normal_Total_Distance;

异步读取纹理

WebGPU 中读取纹理是一个异步操作,而从同步改成异步会影响 render service 接口。antvis/g-device-api#130

// before
readPixels = (options: IReadPixelsOptions) {
  readback.readTextureSync();
}

// after
readPixels = async (options: IReadPixelsOptions) {
  await readback.readTexture();
}

这里的改动没法避免,在 Babylon.js 中也是 breaking change:
https://doc.babylonjs.com/setup/support/webGPU/webGPUBreakingChanges#readpixels-is-now-asynchronous

纹理存储格式

rgba8unorm 和 bgra8unorm 这两种纹理格式在 Shader 中都按 rgba 访问,但内存中的存储却不一样:
https://www.w3.org/TR/WGSL/#texel-format-bgra8unorm

由于我们使用的是 bgra8unorm,因此在拾取后需要交换 b 和 r 再 decode 回 feature id。

// before
const result = await readback.readTexture();

// after
const result = await readback.readTexture();
// Since we use U8_RGBA_RT format in render target, need to change bgranorm -> rgba here.
if (this.viewportOrigin !== ViewportOrigin.LOWER_LEFT) {
  for (let j = 0; j < result.length; j += 4) {
    // Switch b and r components.
    const t = result[j];
    result[j] = result[j + 2];
    result[j + 2] = t;
  }
}

不支持创建宽高为 0 的纹理

报错信息如下:

error: "The texture size ([Extent3D width:0, height:0, depthOrArrayLayers:1]) or mipLevelCount (1) is empty.
- While validating [TextureDescriptor].
- While calling [Device].CreateTexture([TextureDescriptor]).

改成宽高为 1

// before
texture = createTexture2D({
  height: 0,
  width: 0,
});
// after
texture = createTexture2D({
  height: 1,
  width: 1,
});

截图测试

针对一些测试用例渲染前需要长时间加载数据,增加了一个钩子 screenshot

let resolveReadyPromise: () => void;
const readyPromise = new Promise((resolve) => {
  resolveReadyPromise = () => {
    resolve(this);
  };
});

// 在 window 上暴露一个 screenshot 方法
await context.exposeFunction('screenshot', async () => {
  resolveReadyPromise();
});

await page.goto(url);
await readyPromise;

测试用例可以适时调用,通知 Playwright 截图:

scene.on('loaded', () => {
// 其他耗时操作

// 可以开始截图
  if (window['screenshot']) {
    window['screenshot']();
  }
}

📝 更新日志

语言 更新描述
🇺🇸 英文
🇨🇳 中文

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • Changelog 已提供或无须提供

@xiaoiver
Copy link
Contributor Author

xiaoiver commented Jan 2, 2024

point image 报错:

The component count (2) of the vertex output at location 0 is different from the component count (4) of the fragment input at location 0.

原因是 fillimage_frag.glsl 中存在多余的 in vec4 v_color;,并且 vertex shader 和 fragment shader 中的 varying 需要保证顺序一致,否则会报错:

// vertex shader
out vec2 v1;
out vec2 v2;

// fragment shader
in vec2 v2;
in vec2 v1; // 顺序不一致会报错

在生成 WGSL 时,会根据 varying 出现的顺序分配 location,因此顺序不一致就没法匹配:

struct VertexOutput {
    @location(0) v1: vec2<f32>,
    @location(1) v2: vec2<f32>,
}

@github-actions github-actions bot added bugfix and removed bugfix labels Jan 2, 2024
@xiaoiver xiaoiver changed the title fix: webgpu point fill example 支持 WebGPU 渲染 Jan 2, 2024
@xiaoiver xiaoiver changed the title 支持 WebGPU 渲染 [WIP] 支持 WebGPU 渲染 Jan 2, 2024
@xiaoiver xiaoiver changed the title [WIP] 支持 WebGPU 渲染 支持 WebGPU 渲染 Jan 2, 2024
@lzxue lzxue added the V3 L7 3.0 升级 label Jan 2, 2024
@lzxue
Copy link
Contributor

lzxue commented Jan 2, 2024

// before
layout(location = 13) in vec3 a_Normal;
layout(location = 14) in float a_Total_Distance;

// after
layout(location = 13) in vec4 a_Normal_Total_Distance;

line 这种可以合并,参与数据映射的 Vertex 目前不能合并,否则会影响数据更新,如shape/size/offset 目前不能合并

@xiaoiver
Copy link
Contributor Author

xiaoiver commented Jan 3, 2024

line 这种可以合并,参与数据映射的 Vertex 目前不能合并,否则会影响数据更新,如shape/size/offset 目前不能合并

是的,所以在 line 这个例子里,把不会发生更新的 a_Normal 和 a_Total_Distance 合并了。

@lzxue lzxue merged commit f699046 into master Jan 9, 2024
10 checks passed
@lzxue lzxue deleted the fix-webgpu branch January 9, 2024 03:36
lzxue pushed a commit that referenced this pull request Jan 10, 2024
* fix: webgpu point fill example

* fix: adjust order of varying in fill image shader

* fix: remove redundant varying in extrude vert shader

* fix: recreate main & depth rt when resizing

* fix: load image in webgpu

* fix: heatmap

* fix: heatmap grid3d in webgpu

* fix: heatmap grid3d in webgpu

* fix: line

* fix: change readpixel from sync to async

* fix: resize picking fbo

* fix: picking in webgpu

* fix: arc line layer

* fix: use diagnosticDerivativeUniformity in water demo

* fix: add render cache

* fix: point text layer

* chore: update point text layer snapshot

* fix: raster layer

* chore: add screenshot callback on test cases

* chore: sleep

* chore: cancel point image test case for now
lzxue added a commit that referenced this pull request Jan 10, 2024
* fix: fillImage中uniform没对齐的bug

* feat: 适配天地图的底图

* chore: 修改天地图map中lngLatToCoord的方法实现

* feat: 添加天地图的markerContainer,但是不能更新其定位

* fix: marker和popup在地图拖动时不跟随的bug

* feat: 图层显隐组件 LayerSwitch 新增单选模式 (#2211)

* feat: layerSwitch组件新增单选属性

* chore: 更新markdown路径

* feat: layerSwitch组件添加单选模式

* chore: 恢复setting配置

* chore: 删除调试代码

---------

Co-authored-by: 谨欣 <[email protected]>

* Fix raster webgl1 (#2213)

* chore: g-device version & dev command

* fix: raster g.LUMINANCE 回滚到webgl1

* chore: publish (#2214)

* fix: single component data texture (#2215)

* fix: 修复图层显隐控件LayerSwitch单选模式下未默认展示单个图层问题 (#2218)

* fix: 修复图层显隐控件LayerSwitch单选模式下未默认展示单个图层问题

* feat: 图层显隐控件选择模式更新时,销毁图层内容重建

* chore: 修复空格

* chore: 新增todo

* feat: 修改单选模式只显示第一个图层逻辑到onAdd函数中

---------

Co-authored-by: 谨欣 <[email protected]>

* chore: multiband rgb raster parse (#2219)

* chore: multiband rgb raster parse

* fix: 单测

* chore: publish (#2220)

* fix: 修复配置更新时,处理单选模式图层问题 (#2221)

Co-authored-by: 谨欣 <[email protected]>

* Update site&新增 raster ndi 计算 (#2222)

* feat: 添加归一化指数 parse

* chore: 更新文档

* Fix encode update (#2229)

* fix: encode update

* fix: encode update

* chore: publish (#2230)

* fix: 修复图层隐藏时,LayerPopup 未跟随隐藏的问题 (#2231)

* chore: publish (#2232)

* fix: 修正L7Plot官网图表示例按钮跳转链接 (#2233)

* fix: 修复配置更新时,处理单选模式图层问题

* feat: 修改函数名

* fix: 修正L7Plot官网图表示例按钮跳转链接

---------

Co-authored-by: 谨欣 <[email protected]>

* chore: publish (#2235)

* Migrate tile layer (#2236)

* fix: 修复栅格瓦片显示

* fix: 修复冲突

* chore: renderer ts  定义

* docs: add 矢量瓦片demo

* fix: clear depth & stencil before rende mask

* chore: update tile snapshot

* chore: update tile vector snapshot

---------

Co-authored-by: yuqi.pyq <[email protected]>

* chore: add threejs demo (#2245)

* chore: add threejs demo

* docs: add screenshot url

---------

Co-authored-by: zhnny <[email protected]>

* 支持 WebGPU 渲染 (#2225)

* fix: webgpu point fill example

* fix: adjust order of varying in fill image shader

* fix: remove redundant varying in extrude vert shader

* fix: recreate main & depth rt when resizing

* fix: load image in webgpu

* fix: heatmap

* fix: heatmap grid3d in webgpu

* fix: heatmap grid3d in webgpu

* fix: line

* fix: change readpixel from sync to async

* fix: resize picking fbo

* fix: picking in webgpu

* fix: arc line layer

* fix: use diagnosticDerivativeUniformity in water demo

* fix: add render cache

* fix: point text layer

* chore: update point text layer snapshot

* fix: raster layer

* chore: add screenshot callback on test cases

* chore: sleep

* chore: cancel point image test case for now

* fix: 合并冲突

* fix: fillImage中uniform没对齐的bug

* chore: 天地图导出类型

---------

Co-authored-by: huyang <[email protected]>
Co-authored-by: Dreammy23 <[email protected]>
Co-authored-by: 谨欣 <[email protected]>
Co-authored-by: @thinkingGIS <[email protected]>
Co-authored-by: xiaoiver <[email protected]>
Co-authored-by: heiyexing <[email protected]>
Co-authored-by: zhnny <[email protected]>
Co-authored-by: zhnny <[email protected]>
Co-authored-by: lzxue <[email protected]>
lzxue added a commit that referenced this pull request Jan 16, 2024
* fix: fillImage中uniform没对齐的bug

* feat: 适配天地图的底图

* chore: 修改天地图map中lngLatToCoord的方法实现

* feat: 添加天地图的markerContainer,但是不能更新其定位

* fix: marker和popup在地图拖动时不跟随的bug

* feat: 图层显隐组件 LayerSwitch 新增单选模式 (#2211)

* feat: layerSwitch组件新增单选属性

* chore: 更新markdown路径

* feat: layerSwitch组件添加单选模式

* chore: 恢复setting配置

* chore: 删除调试代码

---------

Co-authored-by: 谨欣 <[email protected]>

* Fix raster webgl1 (#2213)

* chore: g-device version & dev command

* fix: raster g.LUMINANCE 回滚到webgl1

* chore: publish (#2214)

* fix: single component data texture (#2215)

* fix: 修复图层显隐控件LayerSwitch单选模式下未默认展示单个图层问题 (#2218)

* fix: 修复图层显隐控件LayerSwitch单选模式下未默认展示单个图层问题

* feat: 图层显隐控件选择模式更新时,销毁图层内容重建

* chore: 修复空格

* chore: 新增todo

* feat: 修改单选模式只显示第一个图层逻辑到onAdd函数中

---------

Co-authored-by: 谨欣 <[email protected]>

* chore: multiband rgb raster parse (#2219)

* chore: multiband rgb raster parse

* fix: 单测

* chore: publish (#2220)

* fix: 修复配置更新时,处理单选模式图层问题 (#2221)

Co-authored-by: 谨欣 <[email protected]>

* Update site&新增 raster ndi 计算 (#2222)

* feat: 添加归一化指数 parse

* chore: 更新文档

* Fix encode update (#2229)

* fix: encode update

* fix: encode update

* chore: publish (#2230)

* fix: 修复图层隐藏时,LayerPopup 未跟随隐藏的问题 (#2231)

* chore: publish (#2232)

* fix: 修正L7Plot官网图表示例按钮跳转链接 (#2233)

* fix: 修复配置更新时,处理单选模式图层问题

* feat: 修改函数名

* fix: 修正L7Plot官网图表示例按钮跳转链接

---------

Co-authored-by: 谨欣 <[email protected]>

* chore: publish (#2235)

* Migrate tile layer (#2236)

* fix: 修复栅格瓦片显示

* fix: 修复冲突

* chore: renderer ts  定义

* docs: add 矢量瓦片demo

* fix: clear depth & stencil before rende mask

* chore: update tile snapshot

* chore: update tile vector snapshot

---------

Co-authored-by: yuqi.pyq <[email protected]>

* chore: add threejs demo (#2245)

* chore: add threejs demo

* docs: add screenshot url

---------

Co-authored-by: zhnny <[email protected]>

* 支持 WebGPU 渲染 (#2225)

* fix: webgpu point fill example

* fix: adjust order of varying in fill image shader

* fix: remove redundant varying in extrude vert shader

* fix: recreate main & depth rt when resizing

* fix: load image in webgpu

* fix: heatmap

* fix: heatmap grid3d in webgpu

* fix: heatmap grid3d in webgpu

* fix: line

* fix: change readpixel from sync to async

* fix: resize picking fbo

* fix: picking in webgpu

* fix: arc line layer

* fix: use diagnosticDerivativeUniformity in water demo

* fix: add render cache

* fix: point text layer

* chore: update point text layer snapshot

* fix: raster layer

* chore: add screenshot callback on test cases

* chore: sleep

* chore: cancel point image test case for now

* fix: 合并冲突

* fix: fillImage中uniform没对齐的bug

* chore: 天地图导出类型

* feat: wms 支持 url service

* feat: tdt fit bounds

* docs: 补充 polygon linear demo

---------

Co-authored-by: huyang <[email protected]>
Co-authored-by: Dreammy23 <[email protected]>
Co-authored-by: 谨欣 <[email protected]>
Co-authored-by: xiaoiver <[email protected]>
Co-authored-by: heiyexing <[email protected]>
Co-authored-by: zhnny <[email protected]>
Co-authored-by: zhnny <[email protected]>
@xiaoiver xiaoiver self-assigned this Jan 22, 2024
@xiaoiver xiaoiver changed the title 支持 WebGPU 渲染 支持 Point / Line / Polygon / Heatmap 在 WebGPU 下的渲染 Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
V3 L7 3.0 升级
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants