-
幀緩存的概念
在 OpenGL 以及大部分的渲染管線中,幀緩存(Frame buffer)是在實際渲染之前的最后一個步驟。幀緩存本質上是一塊內存或者硬件中的空間,負責保存需要渲染圖像的像素相關信息。[1]

幀緩存是一個集合概念,因為幀緩存的內部包括(但不局限於):
- 顏色緩存 Color buffer:記錄像素顏色信息,很多帖子也將顏色緩沖當作幀緩沖的主體。 [2]
- 深度緩存 Z buffer:記錄像素深度值。
- 模塊緩存 Stencil buffer:限制渲染區域,可以和深度緩存一起創造不同的渲染效果 。[3]
- (還有其他的緩沖,在此不做贅述)
-
為什么需要幀緩存
幀緩存的存在是為了在渲染到屏幕或者說傳到窗口緩沖區之前能對圖像進行后期處理 (Post-processing)等其他操作。幀緩存也實現了離屏渲染。
-
離屏渲染(Off-screen rendering)
這里摘自 [4] :
GPU屏幕渲染有以下兩種方式: On-Screen Rendering意為當前屏幕渲染,指的是GPU的渲染操作是在當前用於顯示的屏幕緩沖區中進行。 Off-Screen Rendering意為離屏渲染,指的是GPU在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操作。
大致意思可以理解為,立刻在屏幕上顯現的渲染是當前屏幕渲染,渲染而不立刻顯現在屏幕上的既是離屏渲染。
離屏渲染可以實現對圖像的后期處理,也可以避免 GPU 因為性能問題導致無法順利繪制一幀的全部內容,從而可以避免因為硬件問題導致的跳幀,也可以用來做抗鋸齒等功能(關於離屏渲染的具體作用還是不是很懂,歡迎指正)
離屏渲染的代價也是比較高的,主要是為空間上(需要單獨開辟一塊內存)和時間上(需要在屏幕渲染緩存和離屏緩存間來回切換)的性能損耗。
-
幀緩存的模擬實現
最近一直在拜讀
// 作者:Yuming Zhou BlauHimmel:Simple-3D-Renderer
// 改動:DamienTian
/* // 幀緩存結構 frameBuffer -> |----8----|----8----|----8----|----8----| R G B zBuffer -> 1 / z |---- h * sizeof(void*)----|----height * sizeof(void*)----|----1024 * sizeof(void*)----|----w * h * 4----|----w * h * 4----|----64----| _frameBuffer _zBuffer _texture frameBuffer zBuffer ptr ->frameBuffer ->zBuffer ->ptr */ void Framebuffer::Init(_INT32 width, _INT32 height, _PVOID buffer) { //需求空間(根據上面空間分配所得) int need = size(void*) * (height * 2 + TEXTURE_MAX_SIZE) + sizeof(char) * width * height * 8; char* ptr = new char[need + 64 * sizeof(char)]; // Framebuffer 指針索引 char* frameBuffer; char* zBuffer; assert(buffer != NULL); // 分配索引空間 _buffer = ptr; _frameBuffer = (unsigned int**)ptr; ptr += sizeof(void*) * height; _zBuffer = (float**)ptr; ptr += sizeof(void*) * height; // 分配實際空間 frameBuffer = ptr; ptr += sizeof(char) * width * height * 4; zBuffer = ptr; ptr += sizeof(char) * width * height * 4; if (buffer != NULL) { frameBuffer = (char*)buffer; } // 鏈接索引與內容 for (auto i = 0; i < height; i++) { _frameBuffer[i] = (unsigned int*)(frameBuffer + sizeof(char) * width * 4 * i);
_zBuffer[i] = (float*)(zBuffer + sizeof(char) * width * 4 * i);
}
// ... 后續內容省略,有興趣看的我強推大佬的代碼!
// 大神代碼的講解:https://www.jianshu.com/p/feef32f96552
}
注:其實代碼中的 _frameBuffer 更像是一個顏色緩存,他存儲的是每一個像素的顏色信息。
而 _buffer 則更像是概念上的幀緩存,在代碼中它包括了顏色緩存和深度緩存兩個部分。
參考資料:
[1] 基本概念:https://blog.csdn.net/weixin_34210740/article/details/93428008?utm_source=app
[2] 顏色緩沖: https://www.oreilly.com/library/view/opengl-programming-guide/9780132748445/ch04lev2sec1.html
[3] 模塊緩沖:https://en.wikipedia.org/wiki/Stencil_buffer
[4] 什么是離屏渲染:https://www.jianshu.com/p/f62e81b72bba
[5] 幀緩存的模擬實現:https://github.com/BlauHimmel/Simple-3D-Renderer
圖片:
OpenGL渲染管線:https://glumpy.github.io/modern-gl.html
