今天要把「資料怎麼從你的程式一路跑到顯卡裡又跑回螢幕」講清楚。
記住三個關鍵字:容量(能放多少)、頻寬(一次能搬多少)、延遲(來回要多久)。
GPU 的世界在乎「吞吐量」勝過「單次反應速度」,所以我們會用正確的地方存正確的資料,讓每一趟搬運都值得。
把整台電腦想成一家超商物流:
你要做的,就是把最常用、要快速反覆取的貨(貼圖、網格、常用緩衝)提前放到顯存;而前台員工(SM)運作時,盡量用到「手邊料盒」(暫存器 / Shared Memory / 快取),把一次搬很多、少走回頭路當成原則。
主記憶體 RAM(CPU 在這) ←→ PCIe/NVLink ←→ 顯存 VRAM(GDDR/HBM)
│
└─ L2 Cache(全卡共享)
├─ L1/Texture/Constant Cache(每個 SM 鄰近)
├─ Shared Memory(每個 SM 的「共用小倉庫」)
└─ Registers(每條執行緒的「口袋」)
口訣:越靠近運算單元越快,但越小。寫 Shader/Compute 時,要想辦法讓資料在近的地方被重複使用,不要老是回大倉庫拿。
struct of arrays(SoA)
取代 array of structs(AoS)
,讓每個欄位連續存放,方便一次併讀。小示意
好(SoA):pos_x[] pos_y[] pos_z[] ← 32 條線程可一次讀一整段
壞(AoS):struct {x,y,z} 重複 ← 每條線程跨很大步去抓 x
類型 | 放哪裡 | 為什麼 |
---|---|---|
網格(頂點/索引) | VRAM 的 Buffer | 會被反覆讀,放顯存快又穩 |
貼圖(顏色/法線/粗糙度) | VRAM 的 Texture | 有 Texture Cache 與硬體取樣器幫你加速 |
Uniform/Push 常數 | 小緩衝或 Push 常數 | 每幀/每 Draw 改變的少量參數 |
大量可讀寫的資料(骨骼、粒子、G-Buffer) | Storage Buffer / Render Targets | 容量大、頻寬夠 |
轉場上傳用 | Staging/Upload Buffer(CPU 可見) | 先放這,再一次搬到 VRAM 減少 PCIe 往返 |
原則:能常駐就常駐到 VRAM。上傳用 staging buffer 以批次拷貝,避免每幀碎片小拷貝。
步驟 1:CPU 準備
載入模型/貼圖 → 建立 Buffer/Texture → 把資料批次拷到顯存(使用 staging buffer/映射)。
步驟 2:綁定與下命令
把要用的資源(Buffer/Texture/Sampler)綁到 Descriptor/BindGroup → 錄製命令(Command Buffer)。
步驟 3:GPU 取資料並運算
VS 讀頂點 → Raster 切片 → FS 取貼圖/算顏色;中間快取會幫你擋掉不少回 VRAM 的次數。
步驟 4:寫回顏色/深度附件
寫入 Render Target(Color/Depth/Stencil);ROP/混色會盡量用硬體壓縮(例如顏色/深度壓縮),省頻寬。
步驟 5:顯示
把最後的影像交給顯示系統(表面交換、垂直同步等),進入下一幀。
ASCII 示意
CPU資料 → [Staging] → VRAM(Buffer/Texture)
│ │
└─Command/Bind─────┘
↓
VS → Raster → FS → ROP
↓
Framebuffer → 螢幕
LINEAR
比 NEAREST
平滑;可搭配 anisotropic
提升斜面清晰度(但會更吃頻寬)。新手務必:能壓縮就壓縮、能做 Mip 就做。這是最划算的優化。
多數行動 GPU 用 Tile-Based Deferred Rendering(TBDR):
把畫面切成很多小瓷磚(tiles),在**片上(on-chip)**就完成深度測試與混色,最後一次性寫回 VRAM。
這麼做能減少外部記憶體讀寫(省電又省帶寬)。
你的策略:減少 overdraw(重複畫同一像素)、善用 Early-Z、避免大量半透明疊加。
R8G8B8A8
就別上 R32G32B32A32
;法線可用兩通道壓縮(或 BC5/ASTC),深度選擇 D24/D32
看需求。每幀大量小拷貝到 GPU
貼圖沒壓縮、沒 Mip
FS 亂跳採樣
大量半透明疊加
Compute/FS 暫存器爆掉
畫面顛倒 / 顏色偏差
float3
,顏色改 UNORM8x4
,觀察載入與繪製成本。把常用資料放近、一次搬多一點、重複利用、少往返。
這就是 GPU 記憶體與資料流的王道。當你會善用 VRAM、快取、Shared Memory 與正確的資源格式,你的畫面會更穩、效能更高,開發也更從容。
我們將進入 PBR(物理式渲染)原理與實作:把「金屬」「粗糙」「法線」「環境反射」這些關鍵概念,一次講清楚,並寫出能跑的最小 PBR Shader。