在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...