国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
進(jìn)階設(shè)定
綁定
時(shí)間 - uniforms
粒子位置 - WGSL 儲(chǔ)存
在頂點(diǎn)著色器中讀取計(jì)算著色器中的粒子位置
逐步運(yùn)行模擬
結(jié)語(yǔ)
首頁(yè) web前端 js教程 WebGPU 教學(xué):網(wǎng)路上的運(yùn)算、頂點(diǎn)和片段著色器

WebGPU 教學(xué):網(wǎng)路上的運(yùn)算、頂點(diǎn)和片段著色器

Jan 17, 2025 am 08:30 AM

WebGPU tutorial: compute, vertex, and fragment shaders on the web

WebGPU 作為全球性技術(shù),可望將尖端的 GPU 運(yùn)算能力帶入 Web 領(lǐng)域,惠及所有使用共享程式碼庫(kù)的消費(fèi)平臺(tái)。

其前身 WebGL 雖然功能強(qiáng)大,但卻嚴(yán)重缺乏計(jì)算著色器功能,限制了應(yīng)用範(fàn)圍。

WGSL(WebGPU 著色器/計(jì)算語(yǔ)言)汲取了 Rust 和 GLSL 等領(lǐng)域的最佳實(shí)踐。

在我學(xué)習(xí)使用 WebGPU 的過(guò)程中,發(fā)現(xiàn)文件中存在一些空白:我希望找到一個(gè)簡(jiǎn)單的起點(diǎn),使用計(jì)算著色器來(lái)計(jì)算頂點(diǎn)和片段著色器的相關(guān)資料。

本教學(xué)中所有程式碼的單一檔案 HTML 可在 http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb 找到-請(qǐng)繼續(xù)閱讀以了解詳細(xì)分解。

以下是該 HTML 在我的網(wǎng)域上運(yùn)行的單次點(diǎn)擊演示:http://m.miracleart.cn/link/bed827b4857bf056d05980661990ccdc WebGPU 的瀏覽器,例如 Chrome 或 Edge http://m.miracleart.cn/link/bae00fb8b4115786ba5dbbb67b9b177a)。

進(jìn)階設(shè)定

這是一個(gè)粒子模擬-它會(huì)隨著時(shí)間推移,按時(shí)間步驟進(jìn)行。

時(shí)間在 JS/CPU 上跟蹤,作為 (float) uniform 傳遞給 GPU。

粒子資料完全在 GPU 上管理——儘管仍然與 CPU 交互,允許分配記憶體並設(shè)定初始值。也可以將資料讀回 CPU,但這在本教程中省略了。

此設(shè)定的神奇之處在於,每個(gè)粒子都與所有其他粒子並行更新,從而在瀏覽器中實(shí)現(xiàn)了令人難以置信的計(jì)算和渲染速度(並行化最大限度地達(dá)到GPU 的核心數(shù)量;我們可以將粒子數(shù)量除以核心數(shù)量以獲得每個(gè)核心每次更新步驟的真實(shí)循環(huán)次數(shù))。

綁定

WebGPU 用於 CPU 與 GPU 之間資料交換的機(jī)制是綁定-JS 陣列(如 Float32Array)可以使用 WebGPU 緩衝區(qū)「綁定」到 WGSL 中的記憶體位置。 WGSL 記憶體位置以兩個(gè)整數(shù)標(biāo)示:組號(hào)和綁定號(hào)。

在我們的例子中,計(jì)算著色器和頂點(diǎn)著色器都依賴兩個(gè)資料綁定:時(shí)間和粒子位置。

時(shí)間 - uniforms

uniform 定義存在於計(jì)算著色器 (http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb#L43) 和頂點(diǎn)著色器(http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb#L69) 中-計(jì)算著色器更新位置,頂點(diǎn)著色器依時(shí)間更新顏色。

讓我們來(lái)看看 JS 和 WGSL 中的綁定設(shè)置,從計(jì)算著色器開始。

<code>const computeBindGroup = device.createBindGroup({
  /*
    參見(jiàn) computePipeline 定義,網(wǎng)址為
    http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb#L102

    它允許將 JS 字符串與 WGSL 代碼鏈接到 WebGPU
  */
  layout: computePipeline.getBindGroupLayout(0), // 組號(hào) 0
  entries: [{
    // 時(shí)間綁定在綁定號(hào) 0
    binding: 0,
    resource: {
      /*
      作為參考,緩沖區(qū)聲明為:

      const timeBuffer = device.createBuffer({
        size: Float32Array.BYTES_PER_ELEMENT,
        usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST})
      })

      http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb#L129
      */
      buffer: timeBuffer
    }
  },
  {
    // 粒子位置數(shù)據(jù)在綁定號(hào) 1(仍在組 0)
    binding: 1,
    resource: {
      buffer: particleBuffer
    }
  }]
});</code>

以及計(jì)算著色器中對(duì)應(yīng)的聲明

<code>// 來(lái)自計(jì)算著色器 - 頂點(diǎn)著色器中也有類似的聲明
@group(0) @binding(0) var<uniform> t: f32;
@group(0) @binding(1) var<storage read_write=""> particles : array<particle>;
</particle></storage></uniform></code>

重要的是,我們透過(guò)匹配 JS 和 WGSL 中的組號(hào)和綁定號(hào),將 JS 端的 timeBuffer 綁定到 WGSL。

這使我們能夠從 JS 控制變數(shù)的值:

<code>/* 數(shù)組中只需要 1 個(gè)元素,因?yàn)闀r(shí)間是單個(gè)浮點(diǎn)值 */
const timeJs = new Float32Array(1)
let t = 5.3
/* 純 JS,只需設(shè)置值 */
timeJs.set([t], 0)
/* 將數(shù)據(jù)從 CPU/JS 傳遞到 GPU/WGSL */
device.queue.writeBuffer(timeBuffer, 0, timeJs);</code>

粒子位置 - WGSL 儲(chǔ)存

我們將粒子位置直接儲(chǔ)存和更新在 GPU 可存取的記憶體中——允許我們利用 GPU 的大規(guī)模多核心架構(gòu)並行更新它們。

並行化是在工作組大小的幫助下協(xié)調(diào)的,在計(jì)算著色器中聲明:

<code>@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
  // ...
}
</u32></code>

@builtin(global_invocation_id) global_id : vec3 值提供執(zhí)行緒標(biāo)識(shí)符。

根據(jù)定義,global_invocation_id = workgroup_id * workgroup_size local_invocation_id-這表示它可以用作粒子索引。

例如,如果我們有 10k 個(gè)粒子,且 workgroup_size 為 64,我們需要調(diào)度 Math.ceil(10000/64) 個(gè)工作組。每次從 JS 觸發(fā)計(jì)算傳遞時(shí),我們將明確地告訴 GPU 執(zhí)行該數(shù)量的工作:

<code>computePass.dispatchWorkgroups(Math.ceil(PARTICLE_COUNT / WORKGROUP_SIZE));</code>

如果PARTICLE_COUNT == 10000 且WORKGROUP_SIZE == 64,我們將啟動(dòng)157 個(gè)工作組(10000/64 = 156.25),每個(gè)工作組的計(jì)算範(fàn)圍local_invocation_id 為0 163(而work_id 到)。由於 157 * 64 = 1048,我們將最終在一個(gè)工作組中進(jìn)行稍微更多的計(jì)算。我們透過(guò)丟棄多餘的呼叫來(lái)處理溢出。

以下是考慮這些因素後計(jì)算著色器的最終結(jié)果:

<code>@compute @workgroup_size(${WORKGROUP_SIZE})
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
  let index = global_id.x;
  // 由于工作組網(wǎng)格未對(duì)齊,因此丟棄額外的計(jì)算
  if (index >= arrayLength(&particles)) {
    return;
  }
  /* 將整數(shù)索引轉(zhuǎn)換為浮點(diǎn)數(shù),以便我們可以根據(jù)索引(和時(shí)間)計(jì)算位置更新 */
  let fi = f32(index);
  particles[index].position = vec2<f32>(
    /* 公式背后沒(méi)有宏偉的意圖 - 只不過(guò)是用時(shí)間+索引的例子 */
    cos(fi * 0.11) * 0.8 + sin((t + fi)/100)/10,
    sin(fi * 0.11) * 0.8 + cos((t + fi)/100)/10
  );
}
</f32></u32></code>

這些值將在計(jì)算傳遞中持續(xù)存在,因?yàn)榱W颖欢x為儲(chǔ)存變數(shù)。

在頂點(diǎn)著色器中讀取計(jì)算著色器中的粒子位置

為了從計(jì)算著色器中在頂點(diǎn)著色器中讀取粒子位置,我們需要一個(gè)唯讀視圖,因?yàn)橹挥杏?jì)算著色器才能寫入儲(chǔ)存。

以下是 WGSL 的聲明:

<code>@group(0) @binding(0) var<uniform> t: f32;
@group(0) @binding(1) var<storage> particles : array<vec2>>;
/*
或等效:

@group(0) @binding(1) var<storage read=""> particles : array<vec2>>;
*/
</vec2></storage></vec2></storage></uniform></code>

嘗試重新使用計(jì)算著色器中相同的 read_write 樣式只會(huì)出錯(cuò):

<code>var with 'storage' address space and 'read_write' access mode cannot be used by vertex pipeline stage</code>

請(qǐng)注意,頂點(diǎn)著色器中的綁定號(hào)碼不必與計(jì)算著色器綁定號(hào)碼相符-它們只需要與頂點(diǎn)著色器的綁定組宣告相符:

<code>const renderBindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{
    binding: 0,
    resource: {
      buffer: timeBuffer
    }
  },
  {
    binding: 1,
    resource: {
      buffer: particleBuffer
    }
  }]
});</code>

我在 GitHub 範(fàn)例程式碼 http://m.miracleart.cn/link/2e5281ee978b78d6f5728aad8f28fedb#L70 中選擇綁定:2——只是為了探索 WebGPU 強(qiáng)加的約束的邊界

逐步運(yùn)行模擬

所有設(shè)定就位後,更新和渲染循環(huán)在 JS 中協(xié)調(diào):

<code>/* 從 t = 0 開始模擬 */
let t = 0
function frame() {
  /*
    為簡(jiǎn)單起見(jiàn),使用恒定整數(shù)時(shí)間步 - 無(wú)論幀速率如何,都會(huì)一致渲染。
  */
  t += 1
  timeJs.set([t], 0)
  device.queue.writeBuffer(timeBuffer, 0, timeJs);

  // 計(jì)算傳遞以更新粒子位置
  const computePassEncoder = device.createCommandEncoder();
  const computePass = computePassEncoder.beginComputePass();
  computePass.setPipeline(computePipeline);
  computePass.setBindGroup(0, computeBindGroup);
  // 重要的是要調(diào)度正確數(shù)量的工作組以處理所有粒子
  computePass.dispatchWorkgroups(Math.ceil(PARTICLE_COUNT / WORKGROUP_SIZE));
  computePass.end();
  device.queue.submit([computePassEncoder.finish()]);

  // 渲染傳遞
  const commandEncoder = device.createCommandEncoder();
  const passEncoder = commandEncoder.beginRenderPass({
    colorAttachments: [{
      view: context.getCurrentTexture().createView(),
      clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
      loadOp: 'clear',
      storeOp: 'store',
    }]
  });
  passEncoder.setPipeline(pipeline);
  passEncoder.setBindGroup(0, renderBindGroup);
  passEncoder.draw(PARTICLE_COUNT);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);

  requestAnimationFrame(frame);
}
frame();</code>

結(jié)語(yǔ)

WebGPU 在瀏覽器中釋放了大規(guī)模平行 GPU 運(yùn)算的強(qiáng)大功能。

它以傳遞方式運(yùn)行——每個(gè)傳遞都有局部變量,透過(guò)具有記憶體綁定的管道啟用(橋接 CPU 記憶體和 GPU 記憶體)。

計(jì)算傳遞允許透過(guò)工作小組協(xié)調(diào)並行工作負(fù)載。

雖然它確實(shí)需要一些繁重的設(shè)置,但我認(rèn)為局部綁定/狀態(tài)樣式比WebGL 的全局狀態(tài)模型有了巨大的改進(jìn)——使其更容易使用,同時(shí)也最終將GPU 計(jì)算的強(qiáng)大功能帶入了Web。

以上是WebGPU 教學(xué):網(wǎng)路上的運(yùn)算、頂點(diǎn)和片段著色器的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語(yǔ)言,各自適用於不同的應(yīng)用場(chǎng)景。 Java用於大型企業(yè)和移動(dòng)應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁(yè)開發(fā)。

JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時(shí)間合作? 如何在JS中與日期和時(shí)間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個(gè)階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過(guò)addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動(dòng)態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯(cuò)誤處理。了解這兩個(gè)階段有助於精確控制JavaScript響應(yīng)用戶操作的時(shí)機(jī)和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語(yǔ)言。 1.Java是靜態(tài)類型、編譯型語(yǔ)言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動(dòng)態(tài)類型、解釋型語(yǔ)言,主要用於網(wǎng)頁(yè)交互和前端開發(fā)。

See all articles