紋理取樣和過濾

2021-07-30 14:05:33 字數 2429 閱讀 5418

在opengl和directx裡有紋理取樣函式vector4 sampler.texture2d(float s,float t),用它可以取得對應紋理座標的紋理值;然而,並不知道這個函式的具體實現是怎麼樣的.事實上從影象讀取的紋理就是乙個陣列,類似這樣:

[cpp]view plain

copy

imgdata=new unsigned char[width*height*3];   

紋理座標可以轉換為陣列的下標,類似這樣:

[cpp]view plain

copy

float u=(float)(width-1)*s;  

float v=(float)(height-1)*(1.0-t);  

int iu=(int)u;  

int iv=(int)v;  

紋理座標s和t的範圍是0到1,這邊採用的是opengl的座標系,y軸從下到上遞增,但是儲存的座標系y軸是從上到下遞增,所以1.0-t做y軸取反以獲得opengl座標系的對應的紋理座標,這邊運算出的u和v的範圍是0到紋理寬和0到紋理高,然後將v乘以紋理寬加上u然後乘以3(乙個紋理包含rgb分量)即可獲得陣列下標:

[cpp]view plain

copy

int imgindex=3*(iv*width+iu);  

最後通過陣列下標取得對應的紋理值:

[cpp]view plain

copy

color.x=(float)imgdata[imgindex]*inv_scale;  

color.y=(float)imgdata[imgindex+1]*inv_scale;  

color.z=(float)imgdata[imgindex+2]*inv_scale;  

這邊直接把1/255作為乙個巨集可以加快運算速度:

[cpp]view plain

copy

#define inv_scale 0.003921568627451

然後return color;即可獲得紋理顏色值,以上就是point/nearest取樣的實現.事實上這是最基本的紋理取樣函式實現,這裡邊還有問題,效果不是很好.

point/nearest取樣固然能夠取得紋理的顏色值,但是效果看上去很差,有大塊的走樣,上面有這樣的**:

[cpp]view plain

copy

int iu=(int)u;  

int iv=(int)v;  

問題就出在這裡,(int)這樣直接拋棄小數點以後的值導致取樣出的相鄰紋理並不連續,那麼用float取樣行嗎? 答案是:不行! 這邊實現的取樣函式是從陣列取值,紋理座標轉為陣列下標,陣列下標不能用float只能用int,那麼就沒辦法了嗎? 並不是,可以對周圍紋理進行取樣然後按照各自比例進行混合,這樣能夠提高顯示效果.原理如下:

例如計算出的u和v類似這樣:3.45,4.55 那麼u就在3到4之間,v在4到5之間,比例是(1-0.45):0.45和(1-0.55):0.55,那麼對(3,4),(4,4),(3,5),(4,5)進行取樣,然後乘以各自比例進行顏色混合計算即可得出經過過濾的顏色值.

具體實現如下:

[cpp]view plain

copy

vector4d sampler::texture2d(float s,float t)   

這樣得出的紋理顏色比之前點取樣的看上去好多了.

現代opengl和directx都有framebuffer/rendertarget功能,有了這項功能可以進行render to texture(渲染到紋理)操作.rtt操作的具體應用有很多,最普遍的應用莫過於shadow map技術.事實上rtt的具體實現方法就是把渲染緩衝區的值複製給紋理陣列,也並沒有多少複雜的,具體實現如下:

[cpp]view plain

copy

void writeframebuffer2sampler(framebuffer* fb,sampler* sampler)   

}  }  

那樣,渲染得到的結果就可以作為紋理使用了.

類似opengl和directx在shader裡呼叫紋理取樣函式,這邊模擬了opengl的shader:

[cpp]view plain

copy

void fragmentshader(fragment input,fragmentout& output)   

fragmentshader在光柵化函式rasterize中呼叫,每生成乙個fragment則呼叫一次fragmentshader.

資料載入參見: 

MipMap(紋理過濾)

mipmap 首先從mipmap的原理說起,它是把一張貼圖按照2的倍數進行縮小。直到1x1。把縮小的圖都儲存起來。在渲染時,根據乙個畫素離眼睛為之的距離,來判斷從乙個合適的圖層中取出texel顏色賦值給畫素。在d3d和ogl都有相對應的api控制接 口透過它的工作原理我們可以發現,硬體總是根據眼睛到...

紋理過濾函式glTexParameteri

opengl 紋理過濾函式gltexparameteri 圖象從紋理圖象空間對映到幀緩衝圖象空間 對映需要重新構造紋理影象,這樣就會造成應用到多邊形上的影象失真 這時就可用gltexparmeteri 函式來確定如何把紋理象素對映成畫素.gltexparameteri int target,int ...

OpenGL學習十九 紋理過濾

當物體放大縮小時導致投影在上面的紋理也隨著變化,opengl為了 優化其細節使其效果更好,因此可以採用紋理過濾 gltexparameteri gl texture 2d,gl texture mag filter,gl nearest gl texture mag filter gl neares...