<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WebGPU學習(十):介紹“GPU實現粒子效果”

      大家好,本文介紹了“GPU實現粒子效果”的基本思想,并推薦了相應的學習資料。

      本文學習webgpu-samplers->computeBoids示例,它展示了如何用compute shader實現粒子效果,模擬鳥群的行為。

      上一篇博文:
      WebGPU學習(九):學習“fractalCube”示例

      下一篇博文:
      WebGPU學習(十一):學習兩個優化:“reuse render command buffer”和“dynamic uniform buffer offset”

      最終渲染結果:
      截屏2019-12-26上午9.38.33.png-26.9kB

      為什么不在CPU端實現粒子效果?

      雖然在CPU端實現會更靈活和可控,但如果粒子數量很大(如上百萬),且與場景有交互,則最好在GPU端實現。

      示例的實現思想

      首先執行compute pass

      代碼如下:

        const numParticles = 1500;
      
        ...
      
        let t = 0;
        return function frame() {
          ...
      
          const commandEncoder = device.createCommandEncoder({});
          {
            const passEncoder = commandEncoder.beginComputePass();
            passEncoder.setPipeline(computePipeline);
            passEncoder.setBindGroup(0, particleBindGroups[t % 2]);
            passEncoder.dispatch(numParticles);
            passEncoder.endPass();
          }
          ...
      
          ++t;
        }
      

      我們對這個pass進行分析:

      particleBindGroups包含兩個storage buffer:ParticlesA和ParticlesB

      ParticlesA存儲了上一幀所有粒子的數據。compute shader首先讀取它,然后計算出下一幀所有粒子的數據,最好寫到ParticlesB中。這樣就打了一個ping-pong操作;

      注:storage buffer在shader中可被讀或寫,而uniform buffer、vertex buffer等在shader中只能被讀

      dispatch到1500個instance,每個instance執行一次compute shader

      compute shader計算每個粒子的數據時,需要遍歷其它的所有粒子,計算相互的交互作用。

      一共有1500個粒子,共需要計算15001500次。
      如果在CPU端執行,只能串行計算,一共需要計算1500
      1500次;
      如果在GPU端執行,GPU有1500個instance,每個instance并行地計算1500次,因此一共只需要計算1500次,大大提高了效率。

      然后執行render pass

      代碼如下:

        const numParticles = 1500;
      
        ...
      
        const renderPipeline = device.createRenderPipeline({
          ...
          vertexState: {
            vertexBuffers: [{
              // instanced particles buffer
              arrayStride: 4 * 4,
              stepMode: "instance",
              attributes: [{
                // instance position
                shaderLocation: 0,
                offset: 0,
                format: "float2"
              }, {
                // instance velocity
                shaderLocation: 1,
                offset: 2 * 4,
                format: "float2"
              }],
            }, {
              // vertex buffer
              arrayStride: 2 * 4,
              stepMode: "vertex",
              attributes: [{
                // vertex positions
                shaderLocation: 2,
                offset: 0,
                format: "float2"
              }],
            }],
          },
          ...
        });
        
        ...
      
        const vertexBufferData = new Float32Array([-0.01, -0.02, 0.01, -0.02, 0.00, 0.02]);
        const verticesBuffer = device.createBuffer({
          size: vertexBufferData.byteLength,
          usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        verticesBuffer.setSubData(0, vertexBufferData);
        
        ...
      
        return function frame() {
          ...
      
          const commandEncoder = device.createCommandEncoder({});
          ...
          {
            const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
            passEncoder.setPipeline(renderPipeline);
            //ParticlesB使用“instance”的stepMode,被設置到第一個vertex buffer中
            passEncoder.setVertexBuffer(0, particleBuffers[(t + 1) % 2]);
            //vertices buffer(包含3個頂點數據,每個頂點數據包含x坐標和y坐標)使用“vertex”的stepMode,被設置到第二個vertex buffer中
            passEncoder.setVertexBuffer(1, verticesBuffer);
            //draw一次,繪制1500個實例(使用ParticlesB的數據),其中每個實例有3個頂點(使用vertices buffer的數據)
            //注:每個粒子作為一個實例,由包含3個頂點的三角形組成
            passEncoder.draw(3, numParticles, 0, 0);
            passEncoder.endPass();
          }
          ...
        }
      

      推薦學習資料

      大家可以參考WebGPU-8,來學習示例的具體的代碼。

      雖然該文對應的示例代碼的版本比較老(如它的示例中是1000個粒子,而不是1500個粒子),但與本文對應的最新版本基本上相同,而且它對示例代碼分析得比較詳細,所以推薦大家學習。

      另外,大家可以通過Get started with GPU Compute on the Web,學習如何使用compute shader計算矩陣運算。

      參考資料

      WebGPU-8
      webgpu-samplers Github Repo

      posted @ 2019-12-26 11:32  楊元超  閱讀(1674)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av麻豆aⅴ无码电影| 亚洲美免无码中文字幕在线| 东方四虎av在线观看| 中文字幕理伦午夜福利片| 超清无码一区二区三区| 国产农村妇女高潮大叫| 久热久热中文字幕综合激情| AV无码免费不卡在线观看 | 亚洲精品一区二区三区小| 亚洲夂夂婷婷色拍ww47| 国产成人毛片无码视频软件 | 亚洲 小说区 图片区 都市| 国产精品国产主播在线观看| 国产色a在线观看| 免费看美女被靠到爽的视频| 免费视频爱爱太爽了| 精品亚洲国产成人痴汉av| 国产69精品久久久久99尤物| 91中文字幕一区在线| 图片区小说区av区| 亚洲精品成人区在线观看| 国产精品视频全国免费观看| 国产sm调教折磨视频| 国产精品乱人伦一区二区| 国产亚洲精品AA片在线爽| 国产精品福利在线观看无码卡一| 91老肥熟女九色老女人| 国产成人a在线观看视频| 色综合色狠狠天天综合网| 日本边添边摸边做边爱的网站| 日本五十路熟女一区二区| 国产高清在线男人的天堂| 国产精品一在线观看| 在国产线视频A在线视频| 亚洲人成网站观看在线观看| 久久人妻精品大屁股一区| 亚洲国产精品综合久久20| 日韩有码中文字幕av| 久久九九久精品国产免费直播| 2021av在线天堂网| 亚洲精品久久麻豆蜜桃|