OpenGL 鏈?zhǔn)綖V鏡(幀緩沖離屏渲染)

OpenGL 編寫(xiě)特效在部分應(yīng)用中可通過(guò)單個(gè)shader實(shí)現(xiàn),即通過(guò)修過(guò)修改頂點(diǎn)著色器或片元著色器實(shí)現(xiàn)。但更多的場(chǎng)景是要求有多個(gè)特效組合而成,例如最終效果是圖片灰度加上下顛倒,效果不復(fù)雜條件下可以通過(guò)修改片元著色器實(shí)現(xiàn),當(dāng)效果復(fù)雜特效、組合特效、特效的模塊化開(kāi)發(fā)都會(huì)通過(guò)鏈?zhǔn)綖V鏡實(shí)現(xiàn)。

一、鏈?zhǔn)綖V鏡概念

鏈?zhǔn)綖V鏡 通過(guò)幀緩沖離屏渲染技術(shù)實(shí)現(xiàn)特效的組合和疊加。通過(guò)多次draw最終實(shí)現(xiàn)預(yù)期效果。

二、渲染流程中的幀緩沖

OpenGL的工作流程,輸入像素?cái)?shù)據(jù)和頂點(diǎn)數(shù)據(jù),兩種數(shù)據(jù)分別操作后,通過(guò)光柵化,得到片段,再經(jīng)過(guò)片段處理,最后繪制到幀緩沖區(qū),最終轉(zhuǎn)化為像素?cái)?shù)據(jù)。OpenGL 管線渲染的最終目的地就是FrameBuffer(幀緩沖)。下面是OpenGL渲染流程圖。


1.jpg

三、幀緩沖對(duì)象

在OpenGL渲染管線中,幾何數(shù)據(jù)和紋理經(jīng)過(guò)多次轉(zhuǎn)化和多次測(cè)試,最后以二維像素的形式顯示在屏幕上。OpenGL管線的最終渲染目的地被稱作幀緩存(framebuffer)。幀緩沖是一些二維數(shù)組和OpenG所使用的存儲(chǔ)區(qū)的集合:顏色緩存、深度緩存、模板緩存和累計(jì)緩存。一般情況下,幀緩存完全由window系統(tǒng)生成和管理,由OpenGL使用。這個(gè)默認(rèn)的幀緩存被稱作“window系統(tǒng)生成”(window-system-provided)的幀緩存。OpenGL允許我們定義我們自己的幀緩沖,也就是說(shuō)我們能夠定義我們自己的顏色緩沖,甚至是深度緩沖和模板緩沖。在一個(gè)幀緩存對(duì)象中有多個(gè)顏色關(guān)聯(lián)點(diǎn)、一個(gè)深度關(guān)聯(lián)點(diǎn),和一個(gè)模板關(guān)聯(lián)。每個(gè)幀緩存中至少有一個(gè)顏色關(guān)聯(lián)點(diǎn),其數(shù)目與實(shí)體顯卡相關(guān)??梢酝ㄟ^(guò)GL_MAX_COLOR_ATTACHMENTS_EXT來(lái)查詢顏色關(guān)聯(lián)點(diǎn)的最大數(shù)目。
需要注意:FBO中并沒(méi)有存儲(chǔ)圖像,只有多個(gè)關(guān)聯(lián)點(diǎn)。

四、自定義幀緩沖

1:創(chuàng)建一個(gè)幀緩沖.

unsigned int fbo;
glGenFramebuffers(1, &fbo);

2:綁定幀緩沖,幀緩沖會(huì)在被綁定時(shí)隱士開(kāi)啟
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

3:渲染到紋理

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

五、渲染鏈條

多個(gè)特效組合結(jié)構(gòu)如下,綁定frame buffer 0 作用是再次激活默認(rèn)幀緩沖,在主窗口中有視覺(jué)效果。


2.png

1:灰度 fragment shaderGray

precision highp float; uniform sampler2D Texture; 
varying vec2 TextureCoordsVarying; 
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main (void) { 
 vec4 mask = texture2D(Texture, TextureCoordsVarying); 
 floatluminance = dot(mask.rgb, W); 
 gl_FragColor = vec4(vec3(luminance), 1.0); 
}

1:上下顛倒 fragment shaderReverse

precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;

void main (void) {
    vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
    gl_FragColor = color;
}

偽代碼如下:

// Step one

unsigned int fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

DrawShaderGray(); //繪制結(jié)果在texture

//setp two  
DrawWithGrayInShaderReverse(texture)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容