OpenGL 程式設計/運動模糊
外觀


除了顏色、深度和模板緩衝區,大多數顯示卡還提供所謂的累積緩衝區。本質上它們是每個顏色精度為 16 位或更高的顏色緩衝區。但是,無法直接繪製到累積緩衝區。相反,只有少數操作可以一次對整個累積緩衝區執行。
glAccum(GL_LOAD, value):將普通顏色緩衝區的內容乘以value複製到累積緩衝區。glAccum(GL_RETURN, value):將累積緩衝區的內容乘以value複製到顏色緩衝區。glAccum(GL_ACCUM, value):將普通顏色緩衝區的內容乘以value新增到累積緩衝區。glAccum(GL_ADD, value):將value新增到累積緩衝區中的所有畫素。glAccum(GL_MULT, value):將累積緩衝區中的所有畫素乘以value。
在所有情況下,value 都是一個浮點數。這些函式可以輕鬆地計算多個幀的(加權)總和或平均值。在本教程的第一部分,我們將看到如何利用它輕鬆地將運動模糊新增到幾乎任何 OpenGL 程式中。
運動模糊發生在物體移動速度過快(相對於相機),或者相機的曝光時間過長,以至於在曝光過程中,某些物體移動了超過半個畫素,因此看起來模糊了。運動模糊通常不希望發生,但在使用真實相機時有時很難避免,因為曝光時間在很大程度上取決於場景中的光量。光線越少,曝光時間越長,運動模糊的效果越強。這是戶外用攝像機拍攝的影片“感覺”與用同一臺攝像機在室內拍攝的影片不同的原因之一。
使用累積緩衝區實際上很容易建立運動模糊效果。OpenGL 應用程式通常的工作方式如下
while(true) {
do_time_evolution(timestep);
draw_scene();
glSwapBuffers();
wait_until_next(timestep);
}
其中函式 do_time_evolution() 負責更新場景中移動物體的座標,以及/或者攝像機本身的移動。繪製完場景後,它會使用 glSwapBuffers() 顯示在螢幕上,並且可以選擇等待一段時間來限制幀率。為了新增運動模糊,您可以多次使用更小的時間步長繪製場景,並且只顯示這些場景的平均值
int n = <number of frames to accumulate>
int i = 0;
while(true) {
do_time_evolution(timestep / n);
draw_scene();
if(i == 0)
glAccum(GL_LOAD, 1.0 / n);
else
glAccum(GL_ACCUM, 1.0 / n);
i++;
if(i >= n) {
i = 0;
glAccum(GL_RETURN, 1.0);
glSwapBuffers();
wait_until_next(timestep);
}
}
透過累積大量幀可以獲得最佳效果,但很快就會受到 GPU 效能的限制。最好將要累積的幀數設定為可配置的,或者嘗試自動確定在一個完整的 timestep 內可以渲染多少幀。
- 將運動模糊新增到任何以前的教程中。更有趣的是迷你傳送門和 glescraft,您可以在其中四處走動。
- 如果您要將後期處理效果新增到場景中,您應該在應用運動模糊之前還是之後進行此操作?
- 如果您的 GPU 沒有提供累積緩衝區,您可以透過渲染到紋理來重新建立 glAccum() 功能嗎?