0

在线

617

用户

184

主题

489

帖子

中文社区

有关WebGPU引擎的技术分析与探讨,包括引擎设计,编辑器,GFX,Shader语言编译器,3D文件转换器等。

145 主题 370 帖子
  • WebGL 与 WebGPU比对[4] - Uniform

    1
    0 赞同
    1 帖子
    195 浏览
    尚无回复
  • 0 赞同
    1 帖子
    251 浏览
    尚无回复
  • WebGPU 的几个最佳实践

    5
    0 赞同
    5 帖子
    617 浏览

    @webgpu 又看了看备注,那段改成“WebGL 诞生之初对压缩纹理的支持不太好,以致于后来用 extension 的方式加载压缩纹理让开发者有点不好受。现在 WebGPU 原生就支持,所以 WebGPU 在这方面还是考虑了历史经验的。”吧

  • WebGL 与 WebGPU比对[3] - 顶点缓冲

    1
    0 赞同
    1 帖子
    192 浏览
    尚无回复
  • WebGPU 中消失的 FBO 和 RBO

    1
    0 赞同
    1 帖子
    171 浏览
    尚无回复
  • WebGPU 中的缓冲映射机制

    1
    0 赞同
    1 帖子
    99 浏览
    尚无回复
  • 关于GPUBindGroupLayout如何理解

    2
    0 赞同
    2 帖子
    128 浏览

    做过羊肉汤吗?GPUBindGroup 就是那包羊肉辅料,GPUBindGroupLayout 就是羊肉辅料的配方表。
    这么比喻有点不妥,其实 bindGroup 主要负责传递到管线的资源的绑定,而 layout 对象是告诉管线进来的资源长啥样(资源的元数据)。

  • WebGPU 中消失的 VAO

    1
    0 赞同
    1 帖子
    175 浏览
    尚无回复
  • WebGL 与 WebGPU 比对[2] - 初始化篇

    1
    0 赞同
    1 帖子
    251 浏览
    尚无回复
  • 0 赞同
    3 帖子
    159 浏览

    @shuangliu 感谢回复👍

  • 顶点格式下的offset: 怎么理解?

    6
    0 赞同
    6 帖子
    226 浏览

    @shuangliu 明白了,感谢您的回复👍

  • WGSL中生成随机数

    4
    0 赞同
    4 帖子
    270 浏览
  • 关于setVertexBuffer()插槽的理解

    2
    0 赞同
    2 帖子
    169 浏览

    我好像明白了,0,1是建立着色器和GPU缓冲区的一种方式代号,把缓冲区里面的顶点数据和颜色数据引用到着色器里面,联系的方式是buffers里的shaderLocation:0 和着色器里的[[location(0)]],因为我在main文件中创建顶点和颜色数据;
    因此在最后的渲染管道中,我需要读取顶点数据和颜色数据的GPUBuffers时,同样也需要进行插槽(通俗讲:一个属性代指一个有序数字)的指向,确保缓冲区内的数据于着色器保持同步进行渲染。

    把顶点坐标和颜色数据放在缓冲区写,是因为main.ts是typescript写成的,有代码提示,相比文本的着色器,调试起来更方便。

    0b4036c9-5928-4dc3-aaf6-efba13ed146d-image.png

    a490cedb-9040-40aa-a2a4-6b9cdc0bfb74-image.png

    af509abe-9493-4a6b-ad7a-6d8d7cf3df50-image.png

  • 0 赞同
    3 帖子
    277 浏览

    兼容的方案性价比有点低,本身webgpu不支持对应的标准和api,非要做则需要引擎额外预编译或js加载时实时转换,相关工作量很大,且很多api很难兼容,需要增加大量冗余的代码,甚至要引入wasm来运行一些底层编译库,导致最后引擎编译的版本体积也会大大增加,并不是一个好方案

  • WGSL | 模块变量和常量的源码案例

    3
    0 赞同
    3 帖子
    250 浏览

    w3c的doc国内可能不容易打开,可以参看Orillusion的官方翻译
    https://www.orillusion.com/zh/wgsl.html#var-and-let

  • WebGPU 更新 texture

    2
    0 赞同
    2 帖子
    301 浏览

    1.首先并不需要每个texture对应一个pipeline,可以在同一pipeline中使用不同的BindGroup,每个group对应不同的texture binding. e.g.

    let sampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear', }); let texture1 = device.createTexture({ ... }); let texture2 = device.createTexture({ ... }); const group1 = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 1, resource: sampler, }, { binding: 2, resource: texture1.createView(), } ] }); const group2 = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 1, resource: sampler, }, { binding: 2, resource: texture2.createView(), } ] });

    然后在 rendering loop 中通过 setBindGroup 切换 group1 和 group 2 即可。

    2.如果一组 textures 是同样的大小和格式,可以直接使用 texture_2d_array 去存储多个 image,这样即使一个group内,也可以在shader中通过切换array的index,来直接切换 texutre.

    对于动态的 video texuture, 我们可以直接使用 importExternalTexture 进行引入,随着video播放,texture 会自动更新

    const video = document.createElement('video'); video.loop = true; video.autoplay = true; video.muted = true; video.src = '...'; await video.play(); const group = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 1, resource: sampler, }, { binding: 2, resource: device.importExternalTexture({ source: video, }) } ] });

    3.对于更新静态的 texutre,可以根据目标 image/texture 的类型进行 copy 更新,目前 webgpu 提供多个copy command,我们一般最主要会用到的:copyExternalImageToTexture ,可以更新外部image到gpu texture:

    let texture = device.createTexture({ ... }); const img1 = document.createElement('img'); img1.src = '....'; await img1.decode(); const image1 = await createImageBitmap(img1); device.queue.copyExternalImageToTexture( { source: image1 }, { texture: texture }, [image1.width, image1.height] ); ... ...js // 更新texture的image const img2 = document.createElement('img'); img2.src = '....'; await img2.decode(); const image2 = await createImageBitmap(img2); device.queue.copyExternalImageToTexture( { source: image2 }, { texture: texture }, [image2.width, image2.height] );

    另外,也可以用 commandEncoder 执行 copyTextureToTexture 进行两个 gpu texutre 之间的copy 更新

    // e.g. 创建两个texture,texture1 用于显示,tempTexture用于接收外部图片,图片loading 后进行 copy 更新 let texture1 = device.createTexture({ ... }); ... let tempTexture = device.createTexture({ ... }); let newImage = await loadImage() // 异步加载图片 device.queue.copyExternalImageToTexture( { source: newImage }, { texture: tempTexture }, [newImage.width, newImage.height] ); const commandEncoder = device.createCommandEncoder(); commandEncoder.copyTextureToTexture( { texture: tempTexture }, { texture: texture1 } ); device.queue.submit([commandEncoder.finish()]);

    其他的更新texture API 使用方法,可以参阅 https://www.orillusion.com/webgpu.html#image-copies

    4.对于 sampler,目前 webgpu 没有直接更新 sampler 的API,只能创建新的 sampler,并使用新的group进行渲染,e.g.

    let linearSampler = device.createSampler({ magFilter: 'linear', minFilter: 'linear', }); const group = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 1, resource: linearSampler, }, { binding: 2, resource: texture } ] }); let nearestSampler = device.createSampler({ magFilter: 'nearest', minFilter: 'nearest', }); const newGroup = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 1, resource: nearestSampler, }, { binding: 2, resource: texture } ] });

    group中其他的resource并不需要重新创建,可以复用

  • WebGL 与 WebGPU 比对[1] 前奏

    1
    0 赞同
    1 帖子
    306 浏览
    尚无回复
  • 此主题已被删除!

    1
    0 赞同
    1 帖子
    97 浏览
    尚无回复
  • Web端渲染引擎框架概述

    1
    0 赞同
    1 帖子
    367 浏览
    尚无回复
  • 0 赞同
    2 帖子
    319 浏览

    Compute Shader是允许我们,把本来在CPU端要做很大计算的一些事情放到GPU来做,而并不是在某些特定的场景才会使用。

    利用GPU计算一直都有,在WebGL的中,我们也经常用vertex/ fragment shader 进行复杂计算,主要用于粒子特效的模拟或仿真,但确实使用不方便。一些纯计算 / AI引擎,比如TensorFlow,也会利用WebGL 模拟进行 GPU 并行计算

    WebGPU 开放 Compute shader 后,可以更方便的进行 GPU 计算开发,粒子系统,AI训练,或者物理系统模拟,可以更高效的开发。

    当然,有了compute管线后,一些经典的渲染场景,例如延迟渲染,光线追踪,主动剔除等复杂的渲染计算成为可能,要比WebGL的开发灵活性和能力强很多。

    除此之外,最简单的使用场景,例如把 mvp transform的矩阵计算放在compute shader中进行,要比写在vertex shader中更灵活,gpu性能利用率更高。