Vertex Texture Fetch(VTF) Fragment Texture Fetch ( FTF )
在vertex shader里也可以檢索紋理。我本來(lái)覺(jué)得這沒(méi)什么好奇怪的,因?yàn)槲乙恢币灿X(jué)得這很當(dāng)然可以啊~當(dāng)初橙書(OpenGL Shading Language Edtion2)也說(shuō)過(guò)texture2D這類函數(shù)不是fragment shader專用的,倒還有texture2DLod這種在vertex shader里專用的(后面一句是馬后炮~),只是我不知道怎么用,在哪里用,以及更重要的:為什么要用。
為什么要在vertex shader里檢索紋理。
都知道,紋理里的一般是一幅圖像,無(wú)論是外部導(dǎo)入的還是通過(guò)FBO等手段渲染到的。既然如此,有意義的當(dāng)然是圖像里的每一個(gè)像素啦,通過(guò)紋理坐標(biāo)檢索紋理中的像素打印到屏幕某個(gè)地方,并可控制細(xì)節(jié)程度……反映在GPU編程中,一般就是把當(dāng)前綁定的紋理的紋理單元(默認(rèn)為0)傳送給Fragment Shader作為sampler,在vertex shader里用gl_TexCoord[0] = glMutiTexCoord0這樣的語(yǔ)句,獲取固定流水線中為每個(gè)頂點(diǎn)設(shè)置好的紋理坐標(biāo)(頂點(diǎn)紋理索引,即glMutiTexCoord0),賦給本質(zhì)為varying的gl_TexCoord[0],讓它帶著紋理坐標(biāo)在光柵化過(guò)程中插值——對(duì)應(yīng)每個(gè)像素點(diǎn)擁有屬于它的插值后像素紋理索引(gl_TexCoord[0]),以此作為參數(shù)用texture2D類函數(shù)檢索紋理sampler。
直接在頂點(diǎn)階段就檢索紋理意義何在?獲得的只是那些頂點(diǎn)的紋理坐標(biāo)檢索出的“孤立”像素值而已。
你認(rèn)識(shí)嗎?GPGPU。
[gpgpu.org]
GPGPU(General Purpose Graphic Process Unit,通用目的圖形處理單元),是應(yīng)用GPU的高速并行能力和浮點(diǎn)運(yùn)算能力進(jìn)行科學(xué)計(jì)算等SIMD類型[單指令多數(shù)據(jù)]的應(yīng)用。在這里,GPU-shader不僅僅著眼于圖形。而GPGPU的一個(gè)重要概念就是:紋理 =? 數(shù)組。是的,為什么不可以呢?紋理確實(shí)就是數(shù)組啊。我們能傳入shader的只有具體的數(shù)值,bool,int,float,vec,matrix,其中最大的matrix4也只有16個(gè)量。那么如果我們要把大量的數(shù)據(jù)傳入shader,譬如一個(gè)巨大的float數(shù)組,怎么辦呢?對(duì)啊,用紋理!這時(shí)候,紋理內(nèi)部每個(gè)數(shù)值不再是像素的值,而是數(shù)組的數(shù)據(jù)項(xiàng)。我們只是通過(guò)紋理這種靈活的媒介,讓數(shù)據(jù)“進(jìn)入”GPU的視野,讓shader可以對(duì)這些數(shù)據(jù)項(xiàng)變量進(jìn)行訪問(wèn)和操作。
順帶一提,現(xiàn)在科學(xué)計(jì)算領(lǐng)域已經(jīng)進(jìn)入GPGPU的進(jìn)化時(shí)代 -CUDA時(shí)代了。好吧,不要扯遠(yuǎn)了。
既然紋理 = 數(shù)組, VTF頂點(diǎn)紋理拾取的存在就不言自明了:其實(shí)不是在拾取含有圖像像素信息的那個(gè)紋理,而是在拾取含有頂點(diǎn)數(shù)據(jù)信息的那個(gè)“數(shù)組”啊!在這里,數(shù)組的索引就是頂點(diǎn)紋理坐標(biāo)……看例子:
//RenderMonkey: //Vertex Program varying vec4 vertColor; uniform sampler2D baseMap;void main( void ) {//vertColor = texture2D(baseMap, gl_MultiTexCoord0.xy); 與下句等價(jià) vertColor = texture2DLod(baseMap, gl_MultiTexCoord0.xy, 0.0); vec4 pos = gl_ModelViewMatrix * (gl_Vertex) ;gl_Position = gl_ProjectionMatrix * pos ; }//Fragment Program varying vec4 vertColor;void main( void ) {gl_FragColor = vertColor; }這個(gè)例子是說(shuō)明:誒?原來(lái)Vertex Shader里也可以做紋理拾取口牙!順帶一提,這里用texture2D,和用“texture2DLod+尾參數(shù)[細(xì)節(jié)參數(shù)LOD] = 0.0”的效果是一樣的:
?
(對(duì)比用。這是FTF,傳統(tǒng)的fragment shader獲取紋理)
(這是VTF,頂點(diǎn)紋理拾取,也就是上面代碼的產(chǎn)物,對(duì)比兩圖哈)
紋理只是普通的紋理。只是為了證明VTF能行- -。把頂點(diǎn)紋理的值做插值,預(yù)料最后的結(jié)果類似于頂點(diǎn)顏色插值,三角片元的顏色在三角的三頂點(diǎn)所獲得的紋理顏色間進(jìn)行線性插值,得出如此“重過(guò)渡味+模糊”的怪象(嘛~這紋理即使是那FTF出來(lái)的也是怪象)。然后測(cè)試texture2DLod這個(gè)函數(shù),把最后的LOD參數(shù)增大調(diào)為0.4:
lod是細(xì)節(jié)參數(shù),這跟以前的FTF(PTF)差不多。好吧,換張紋理后,再用VTF做點(diǎn)更有趣的:
//RenderMonkey: //Vertex Program varying vec4 vertColor; uniform sampler2D baseMap; void main( void ) { vertColor = texture2DLod(baseMap, gl_MultiTexCoord0.xy, 0.0);vec4 offset = vec4(0.0);if(gl_Vertex.z > 0.0)offset = vertColor;else if(gl_Vertex.z < 0.0)offset = vec4(1.0)-vertColor;vec4 pos = gl_ModelViewMatrix * (gl_Vertex+ offset) ; gl_Position = gl_ProjectionMatrix * pos ; } //Fragment Program varying vec4 vertColor; void main( void ) { gl_FragColor = vertColor; }能猜到結(jié)果變成這樣嗎?哈,VTF出來(lái)的vertColor果然充滿力量:
另外一個(gè)例子則用VTF做點(diǎn)有意義的事情。還記得高度圖紋理嗎?(我在[Terrain Texture-Array Demo] 里也用到過(guò)~)
//RenderMonkey: //Vertex Program varying vec2 texCoord; uniform sampler2D Texture0;void main(void) {vec4 vcol = texture2D( Texture0, gl_MultiTexCoord0.xy);float gray = 0.2990*vcol.r + 0.5870*vcol.g + 0.1140*vcol.b;vec4 pos = gl_Vertex;pos.z = pos.z * (1.0 - 5.0*gray);gl_Position = gl_ModelViewProjectionMatrix * pos;texCoord = gl_MultiTexCoord0.xy; }//Fragment Program uniform sampler2D Texture0; varying vec2 texCoord;void main(void) {gl_FragColor = texture2D( Texture0, texCoord ); }這里本來(lái)只有一個(gè)平整的網(wǎng)格,和一張類似高度圖的紋理。運(yùn)用VTF把頂點(diǎn)對(duì)應(yīng)的紋理坐標(biāo)的像素值拉出來(lái)轉(zhuǎn)化為灰度(轉(zhuǎn)化法同見(jiàn)[基于亮度的圖像二值化處理] ),并轉(zhuǎn)化為該網(wǎng)格頂點(diǎn)的“高度”。最后的紋理只是平鋪上去(那不是陰影哦)。看,灰度高的地方對(duì)應(yīng)的高度高,灰度低的地方對(duì)應(yīng)的高度低。這就是高度場(chǎng)啊,這就是VTF最典型的應(yīng)用啊!
在Vertex Shader里面,通過(guò)紋理坐標(biāo)的檢取,VTF獲取的是真正的“高度值”數(shù)據(jù)……只是這些數(shù)據(jù)被儲(chǔ)存在一張紋理上罷了。
總結(jié)
以上是生活随笔為你收集整理的Vertex Texture Fetch(VTF) Fragment Texture Fetch ( FTF )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【wordpress基础教程一】:wor
- 下一篇: [杭电ACM]1012u Calcula