AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

WebGPU 入門:繪制一個三角形

來源: 責編: 時間:2023-11-01 09:19:00 270觀看
導讀大家好,我是前端西瓜哥。今天我們來入門 WebGPU,來寫一個圖形版本的 Hello World,即繪制一個三角形。WebGPU 是什么?WebGPU 是一個正在開發中的潛在 Web 標準和 JavaScript API,目標是提供 “現代化的 3D 圖形和計算能力”

06q28資訊網——每日最新資訊28at.com

大家好,我是前端西瓜哥。06q28資訊網——每日最新資訊28at.com

今天我們來入門 WebGPU,來寫一個圖形版本的 Hello World,即繪制一個三角形。06q28資訊網——每日最新資訊28at.com

WebGPU 是什么?

WebGPU 是一個正在開發中的潛在 Web 標準和 JavaScript API,目標是提供 “現代化的 3D 圖形和計算能力”。06q28資訊網——每日最新資訊28at.com

簡單來說,WebGPU 提供一個更現代的 Web 上的圖形渲染標準。06q28資訊網——每日最新資訊28at.com

WebGPU 的出現就是為了取代 WebGL 的,因為后者的 API 實在有些過時,無法利用好現代 GPU 的一些高級特性,本身的 API 設計也較難使用。06q28資訊網——每日最新資訊28at.com

相比 WebGL,WebGPU 有更好的性能表現,API 更底層更靈活,并支持更高級的現代特性,比如計算著色器。06q28資訊網——每日最新資訊28at.com

毫無疑問,WebGPU 是前端圖形渲染的未來,值得去學習一下。06q28資訊網——每日最新資訊28at.com

像是以性能著稱的前端圖形庫 PixiJS,也開始進行支持 WebGPU 的工作,并在最近發布了預覽版本,聲稱性能將是 WebGL 的 2.5 倍。06q28資訊網——每日最新資訊28at.com

06q28資訊網——每日最新資訊28at.com

不過目前 WebGPU 還不夠成熟,仍有許多工作要做,且只有少數瀏覽器的最新版本直接支持或通過設置開啟。06q28資訊網——每日最新資訊28at.com

即使之后所有瀏覽器都支持了,舊版本瀏覽器還是不支持的,離大范圍使用還有相當長的一段路要走。06q28資訊網——每日最新資訊28at.com

06q28資訊網——每日最新資訊28at.com

只能說未來可期。06q28資訊網——每日最新資訊28at.com

但生產中,我們可以做一個回退機制:如果瀏覽器支持 WebGPU,我們用 WebGPU 去渲染,如果不支持就回滾到 WebGL。06q28資訊網——每日最新資訊28at.com

只要在底層渲染方案上封裝一層渲染器 renderer,就像 PixiJS 現在做的事情一樣,個人還是比較期待它在性能上的提升的。06q28資訊網——每日最新資訊28at.com

繪制三角形

OK,我們開始用 WebGPU 繪制一個三角形。06q28資訊網——每日最新資訊28at.com

確保你的瀏覽器支持 WebGPU,建議用 Chrome,并更新到最新版本。06q28資訊網——每日最新資訊28at.com

這里我們創建一個寬高各為 300 的 canvas 元素,用于繪制圖形。06q28資訊網——每日最新資訊28at.com

<canvas width="300" height="300"></canvas>

初始化 WebGPU 相關的一些對象。06q28資訊網——每日最新資訊28at.com

adapter 和 device

創建一個適配器對象 adapter,適配器是一個 GPU 物理硬件設備的抽象。06q28資訊網——每日最新資訊28at.com

const adapter = await navigator.gpu.requestAdapter();

requestAdapter() 方法會查看系統上所有可用的 GPU 設備,并選擇其中合適的適配器。該方法可以傳一些參數,去按條件匹配。比如 { powerPreference: 'low-power' } 表示優先使用低能耗的 GPU。06q28資訊網——每日最新資訊28at.com

此外,這個方法返回的是一個 Promise,即它是 異步的,需要用 await 的方式去等待異步的結果。06q28資訊網——每日最新資訊28at.com

然后基于 adapter,調用 requestDevice 方法拿到設備對象 device。06q28資訊網——每日最新資訊28at.com

device 可以理解為 adapter 的一個會話。做個比喻的話 adapter 是一個公司,device 是一個具體干活的人。06q28資訊網——每日最新資訊28at.com

const device = await adapter.requestDevice();

requestDevice() 方法也可以傳入配置項,去開啟一些高級特性,或是指定一些硬件限制,比如最大紋理尺寸。06q28資訊網——每日最新資訊28at.com

配置 canvas

類似 canvas 2d 和 webgl,我們需要通過 canvas 元素拿到上下文。06q28資訊網——每日最新資訊28at.com

const canvas = document.querySelector('canvas');const ctx = canvas.getContext('webgpu');

接著是調用 ctx.configure() 方法配置剛剛聲明的 device 對象和像素格式。06q28資訊網——每日最新資訊28at.com

const canvasFormat = navigator.gpu.getPreferredCanvasFormat();// 給上下文配置 device 對象和ctx.configure({  device,  format: canvasFormat,});

navigator.gpu.getPreferredCanvasFormat() 會返回當前環境合適的像素格式的字符串標識,通常是 'bgra8unorm',表示用 8 位無符號整數來表示藍色、綠色、紅色和透明度四個分量。06q28資訊網——每日最新資訊28at.com

設置背景色

創建命令編碼器 GPUCommandEncoder 實例,它用于編碼需要提交給 GPU 的命令。06q28資訊網——每日最新資訊28at.com

const encoder = device.createCommandEncoder();

開啟一個新的渲染通道(Render Pass),這里清空顏色緩沖區時填充了一個淺藍色背景。06q28資訊網——每日最新資訊28at.com

和 WebGL 一樣,使用 RGBA 的格式,每個分量為 0 到 1 的范圍,比如 { r: 1, g: 0, b: 0, a: 1 } 表示紅色,或者你可以用數組的形式 [1, 0, 0, 1]。06q28資訊網——每日最新資訊28at.com

const pass = encoder.beginRenderPass({  // 顏色附件,一個用于存儲渲染輸出顏色數據的紋理  colorAttachments: [    {      // 要渲染到的目標      view: ctx.getCurrentTexture().createView(),      // 渲染前清空顏色緩沖區      loadOp: 'clear',      // 清除顏色為淺藍色,不設置會默認使用黑色      clearValue: { r: 0.6, g: 0.8, b: 0.9, a: 1 },      // 渲染結果會被保留在紋理中,后序好繪制到 canvas 上      storeOp: 'store',    },  ],});

我們先不繪制三角形,看看背景的渲染效果,為此我們提前執行下面代碼:06q28資訊網——每日最新資訊28at.com

// 這里是繪制三角形的代碼,之后會實現pass.end(); // 完成指令隊列的記錄const commandBuffer = encoder.finish(); // 結束編碼device.queue.submit([commandBuffer]); // 提交給 GPU 命令隊列

06q28資訊網——每日最新資訊28at.com

遠峰藍。06q28資訊網——每日最新資訊28at.com

創建緩沖區

先說說 WebGPU 的坐標系,它和 WebGL 一樣,原點在畫布中心,x 軸向右,y 軸向上,取值范圍都是 -1 到 1。06q28資訊網——每日最新資訊28at.com

06q28資訊網——每日最新資訊28at.com

聲明頂點數據。這些頂點為組成三角形的三個坐標。06q28資訊網——每日最新資訊28at.com

const vertices = new Float32Array([  -0.5, -0.5,  0.5, -0.5,  0.5, 0.5,]);

然后創建頂點緩沖區:06q28資訊網——每日最新資訊28at.com

const vertexBuffer = device.createBuffer({  // 標識,字符串隨意寫,報錯時會通過它定位  label: 'Triangle Vertices',  // 緩沖區大小,這里是 24 字節。6 個 4 字節(即 32 位)的浮點數  size: vertices.byteLength,  // 標識緩沖區用途(1)用于頂點著色器(2)可以從 CPU 復制數據到緩沖區  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,});

label 方便我們定位錯誤位置:06q28資訊網——每日最新資訊28at.com

06q28資訊網——每日最新資訊28at.com

接著是將頂點數據復制到緩沖區:06q28資訊網——每日最新資訊28at.com

device.queue.writeBuffer(vertexBuffer, /* bufferOffset */ 0, vertices);

參數 bufferOffset 表示緩沖區偏移多少字節數的位置寫入數據。06q28資訊網——每日最新資訊28at.com

讀取方式

設置緩沖區的讀取方式。06q28資訊網——每日最新資訊28at.com

const vertexBufferLayout = {  // 每組讀 8 個字節。一個坐標為兩個浮點數(2 * 4字節)  arrayStride: 2 * 4,   attributes: [    {      // 指定數據格式,這樣 WebGPU 才知道該如何解析,格式為 2 個 32位浮點數      format: 'float32x2',      offset: 0, // 從每組的第一個數字開始      shaderLocation: 0, // 頂點著色器中的位置    },  ],};

attributes 是一個數組,這里我們只有頂點要讀,所以只有一個數組元素。如果引入了顏色值并和頂點放在一起,我們就要多聲明一個數組元素,并將 offset 指定到顏色的位置。06q28資訊網——每日最新資訊28at.com

這個對象此時還沒用到,后面設置渲染流水線時會用到。06q28資訊網——每日最新資訊28at.com

著色器

聲明 WebGPU 的著色器,創建著色器模塊(GPUShaderModule)。06q28資訊網——每日最新資訊28at.com

WebGPU 使用特有的 WGSL 著色器語言,頂點著色器和片元著色器可以寫在一起的。06q28資訊網——每日最新資訊28at.com

// 創建著色器模塊const vertexShaderModule = device.createShaderModule({  label: 'Vertex Shader',  code: `    @vertex    fn vertexMain(@location(0) pos: vec2f) -> @builtin(position) vec4f {      return vec4f(pos, 0, 1);    }    @fragment    fn fragmentMain() -> @location(0) vec4f {      return vec4f(1, 0, 0, 1);    }  `,});

頂點著色器函數。06q28資訊網——每日最新資訊28at.com

@vertex fn vertexMain(@location(0) pos: vec2f) -> @builtin(position) vec4f {  return vec4f(pos, 0, 1);}
  • @vertex:裝飾器,表示頂點著色器主函數。
  • @location(0):緩沖區讀取方式設置的 shaderLocation,這里拿到了兩個浮點數。
  • vec2f:兩個浮點數的向量,同理,vec4f 為 4 浮點數的向量。
  • -> @builtin(position):表示函數的返回值會被設置為內置的頂點位置變量。WebGPU 是利用函數的返回值配合修飾符的方式進行內部變量賦值的。

片元著色器。06q28資訊網——每日最新資訊28at.com

@fragmentfn fragmentMain() -> @location(0) vec4f {  return vec4f(1, 0, 0, 1); // 紅色}
  • @fragment 表示片元著色器主函數。
  • -> @location(0) 表示將返回的顏色輸出到位置為 0 的顏色附件上,簡單來說,就是給對應點設置為對應顏色。

渲染流水線

創建渲染流水線,也就是把之前的設置組合起來,用哪個著色器的哪個函數作為入口、如何讀取緩沖區等。06q28資訊網——每日最新資訊28at.com

const pipeline = device.createRenderPipeline({  label: 'pipeline', // 標識,定位錯誤用  layout: 'auto', // 自動流水線布局  vertex: {    module: vertexShaderModule, // 著色器模塊    entryPoint: 'vertexMain', // 入口函數為 vertexMain    buffers: [vertexBufferLayout], // 讀取緩沖區的方式  },  fragment: {    module: vertexShaderModule,    entryPoint: 'fragmentMain',    targets: [      {        format: canvasFormat, // 輸出到 canvas 畫布上      },    ],  },});

將渲染流水線設置到 pass 上。06q28資訊網——每日最新資訊28at.com

pass.setPipeline(pipeline);

將緩沖區綁定到管線的第一個頂點緩沖槽(slot)。06q28資訊網——每日最新資訊28at.com

pass.setVertexBuffer(0, vertexBuffer);

繪制圖元,這里要設置繪制幾組,一組是兩個點,所以要處以 2。06q28資訊網——每日最新資訊28at.com

pass.draw(vertices.length / 2);

然后就是前面講過的收尾代碼。06q28資訊網——每日最新資訊28at.com

pass.end(); // 完成指令隊列的記錄const commandBuffer = encoder.finish(); // 結束編碼device.queue.submit([commandBuffer]); // 提交給 GPU 命令隊列

至此,一個三角形就畫好了。06q28資訊網——每日最新資訊28at.com

繪制結果

06q28資訊網——每日最新資訊28at.com

完整代碼

線上 demo 演示:06q28資訊網——每日最新資訊28at.com

https://codesandbox.io/s/lg4w27?file=/src/index.mjs。06q28資訊網——每日最新資訊28at.com

完整代碼:06q28資訊網——每日最新資訊28at.com

const render = async () => {  const adapter = await navigator.gpu.requestAdapter();  const device = await adapter.requestDevice();  const canvas = document.querySelector('canvas');  const ctx = canvas.getContext('webgpu');  const canvasFormat = navigator.gpu.getPreferredCanvasFormat();  ctx.configure({    device,    format: canvasFormat,  });  const encoder = device.createCommandEncoder();  const pass = encoder.beginRenderPass({    colorAttachments: [      {        view: ctx.getCurrentTexture().createView(),        loadOp: 'clear',        clearValue: { r: 0.6, g: 0.8, b: 0.9, a: 1 },        storeOp: 'store',      },    ],  });  // 創建頂點數據  // prettier-ignore  const vertices = new Float32Array([    -0.5, -0.5,    0.5, -0.5,    0.5, 0.5,  ]);  // 緩沖區  const vertexBuffer = device.createBuffer({    // 標識,字符串隨意寫,報錯時會通過它定位,    label: 'Triangle Vertices',    // 緩沖區大小,這里是 24 字節。6 個 4 字節(即 32 位)的浮點數    size: vertices.byteLength,    // 標識緩沖區用途(1)用于頂點著色器(2)可以從 CPU 復制數據到緩沖區    // eslint-disable-next-line no-undef    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,  });  // 將頂點數據復制到緩沖區  device.queue.writeBuffer(vertexBuffer, /* bufferOffset */ 0, vertices);  // GPU 應該如何讀取緩沖區中的數據  const vertexBufferLayout = {    arrayStride: 2 * 4, // 每一組的字節數,每組有兩個數字(2 * 4字節)    attributes: [      {        format: 'float32x2', // 每個數字是32位浮點數        offset: 0, // 從每組的第一個數字開始        shaderLocation: 0, // 頂點著色器中的位置      },    ],  };  // 著色器用的是 WGSL 著色器語言  const vertexShaderModule = device.createShaderModule({    label: 'Vertex Shader',    code: `      @vertex      fn vertexMain(@location(0) pos: vec2f) -> @builtin(position) vec4f {        return vec4f(pos, 0, 1);      }      @fragment      fn fragmentMain() -> @location(0) vec4f {        return vec4f(1, 0, 0, 1);      }    `,  });  // 渲染流水線  const pipeline = device.createRenderPipeline({    label: 'pipeline',    layout: 'auto',    vertex: {      module: vertexShaderModule,      entryPoint: 'vertexMain',      buffers: [vertexBufferLayout],    },    fragment: {      module: vertexShaderModule,      entryPoint: 'fragmentMain',      targets: [        {          format: canvasFormat,        },      ],    },  });  pass.setPipeline(pipeline);  pass.setVertexBuffer(0, vertexBuffer);  pass.draw(vertices.length / 2);  pass.end();  const commandBuffer = encoder.finish();  device.queue.submit([commandBuffer]);};render();

結尾

本文講解了如何用 WebGPU 繪制一個三角形。可以看到它和 WebGL 的邏輯有很多共同之處的,都要創建緩沖區、著色器、定義讀取方式。06q28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-16287-0.htmlWebGPU 入門:繪制一個三角形

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 掌握Spring事件監聽器的內部邏輯與實現

下一篇: 轉轉Flutter實踐之路

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 把LangChain跑起來的三個方法

    使用LangChain開發LLM應用時,需要機器進行GLM部署,好多同學第一步就被勸退了,那么如何繞過這個步驟先學習LLM模型的應用,對Langchain進行快速上手?本片講解3個把LangChain跑起來
  • Flowable工作流引擎的科普與實踐

    一.引言當我們在日常工作和業務中需要進行各種審批流程時,可能會面臨一系列技術和業務上的挑戰。手動處理這些審批流程可能會導致開發成本的增加以及業務復雜度的上升。在這
  • 之家push系統迭代之路

    前言在這個信息爆炸的互聯網時代,能夠及時準確獲取信息是當今社會要解決的關鍵問題之一。隨著之家用戶體量和內容規模的不斷增大,傳統的靠"主動拉"獲取信息的方式已不能滿足用
  • 當家的盒馬,加速謀生

    來源 | 價值星球Planet作者 | 歸去來自己&ldquo;當家&rdquo;的盒馬,開始加速謀生了。據盒馬官微消息,盒馬計劃今年開放生鮮供應鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經與
  • 三星推出Galaxy Tab S9系列平板電腦以及Galaxy Watch6系列智能手表

    2023年7月26日,三星電子正式發布了Galaxy Z Flip5與Galaxy Z Fold5。除此之外,Galaxy Tab S9系列平板電腦以及三星Galaxy Watch6系列智能手表也同期
  • 電博會上海爾智家模擬500平大平層,還原生活空間沉浸式體驗

    電博會為了更好地讓參展觀眾真正感受到智能家居的絕妙之處,海爾智家的程傳嶺先生同樣介紹了展會上海爾智家的模擬500平大平層,還原生活空間沉浸式體驗。程傳
  • Meta盲目擴張致超萬人被裁,重金押注元宇宙而前景未明

    圖片來源:圖蟲創意日前,Meta創始人兼CEO 馬克&middot;扎克伯發布公開信,宣布Meta計劃裁員超11000人,占其員工總數13%。他公開承認了自己的預判失誤:&ldquo;不僅
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top