21世紀(jì)最糟糕的發(fā)明當(dāng)屬馬賽克慨默,阻止了人類對文明的探尋(哈哈哈,其奧秘自行腦補哈~)
今天就來說一下OpenGL里這令人不爽的馬賽克實現(xiàn)原理
馬賽克原理總結(jié)為一句話弧腥,就是選擇一塊區(qū)域厦取,此區(qū)域的顏色展示統(tǒng)一使用原來該區(qū)域的某個點的顏色值。
其根據(jù)算法不一樣管搪,可以展示大小不同虾攻,形狀不同,效果不同的各種被處理后的馬賽克圖片更鲁。
如圖對比:
一般來說四邊形馬賽克在定義好精度區(qū)域的情況下霎箍,還是較容易實現(xiàn)的,現(xiàn)在重點講一下六邊形馬賽克的實現(xiàn)原理:
首先明白六邊形區(qū)域的劃分澡为,邊長與寬的比值漂坏,因為滿足平鋪平面的圖形是有形狀要求的,分割成由六邊形后讓每個六邊形中的顏色相同(直接取六邊形中心點像素RGB較方便,我們這里采用的就是這種方法) 將它進(jìn)?行行分割顶别,取每個六邊形的中心點畫出?個矩陣谷徙,如下:
如上圖,畫出很多長和寬?例為 3:√3 的的矩形陣筋夏。然后我們可以 對每個點進(jìn)行編號蒂胞,如上圖中,采用坐標(biāo)系標(biāo)記.?
假如我們的屏幕的左上點為上圖的(0,0)點条篷,則屏幕上的任?一點我 們找到它所對應(yīng)的那個矩形了了骗随。?
假定我們設(shè)定的矩陣?比例例為3*LEN : √3*LEN,那么屏幕上的任意點(x, y)所對應(yīng)的矩陣坐標(biāo)為(int(x/(3*LEN)), int(y/ (√3*LEN)))赴叹。?
//wx,wy -> 表示紋理坐標(biāo)在所對應(yīng)的矩陣坐標(biāo)為?
int wx = int(x /( 1.5 * length));?
int wy = int(y /(TR * length));?
片元著色器代碼main{}核心算法部分:
floatlength= mosaicSize;
? ? float TR = 0.866025;
? ? floatTB =1.5;
? ? floatx = TextureCoordsVarying.x;
? ? floaty = TextureCoordsVarying.y;
? ? intwx =int(x / TB /length);
? ? intwy =int(y / TR /length);
? ? vec2v1, v2, vn;
? ? if(wx/2*2== wx) {
? ? ? ? if(wy/2*2== wy) {
? ? ? ? ? ? //(0,0),(1,1)
? ? ? ? ? ? v1 =vec2(length*1.5*float(wx),length* TR *float(wy));
? ? ? ? ? ? v2 =vec2(length*1.5*float(wx +1),length* TR *float(wy +1));
? ? ? ? }?else?{
? ? ? ? ? ? //(0,1),(1,0)
? ? ? ? ? ? v1 =vec2(length*1.5*float(wx),length* TR *float(wy +1));
? ? ? ? ? ? v2 =vec2(length*1.5*float(wx +1),length* TR *float(wy));
? ? ? ? }
? ? }?else?{
? ? ? ? if(wy/2*2== wy) {
? ? ? ? ? ? //(0,1),(1,0)
? ? ? ? ? ? v1 =vec2(length*1.5*float(wx),length* TR *float(wy +1));
? ? ? ? ? ? v2 =vec2(length*1.5*float(wx +1),length* TR *float(wy));
? ? ? ? }?else?{
? ? ? ? ? ? //(0,0),(1,1)
? ? ? ? ? ? v1 =vec2(length*1.5*float(wx),length* TR *float(wy));
? ? ? ? ? ? v2 =vec2(length*1.5*float(wx +1),length* TR *float(wy +1));
? ? ? ? }
? ? }
? ? floats1 =sqrt(pow(v1.x - x,2.0) +pow(v1.y - y,2.0));
? ? floats2 =sqrt(pow(v2.x - x,2.0) +pow(v2.y - y,2.0));
? ? if(s1 < s2) {
? ? ? ? vn = v1;
? ? }?else?{
? ? ? ? vn = v2;
? ? }
?? ?vec4color =texture2D(Texture, vn);
? ? gl_FragColor= color;