21世纪最糟糕的发明当属马赛克,阻止了人类对文明的探寻(哈哈哈,其奥秘自行脑补哈~)
今天就来说一下OpenGL里这令人不爽的马赛克实现原理
马赛克原理总结为一句话,就是选择一块区域,此区域的颜色展示统一使用原来该区域的某个点的颜色值。
其根据算法不一样,可以展示大小不同,形状不同,效果不同的各种被处理后的马赛克图片。
如图对比:
一般来说四边形马赛克在定义好精度区域的情况下,还是较容易实现的,现在重点讲一下六边形马赛克的实现原理:
首先明白六边形区域的划分,边长与宽的比值,因为满足平铺平面的图形是有形状要求的,分割成由六边形后让每个六边形中的颜色相同(直接取六边形中心点像素RGB较方便,我们这里采用的就是这种方法) 将它进⾏行行分割,取每个六边形的中心点画出⼀个矩阵,如下:
如上图,画出很多长和宽⽐例为 3:√3 的的矩形阵。然后我们可以 对每个点进行编号,如上图中,采用坐标系标记.
假如我们的屏幕的左上点为上图的(0,0)点,则屏幕上的任⼀一点我 们找到它所对应的那个矩形了了。
假定我们设定的矩阵⽐比例例为3*LEN : √3*LEN,那么屏幕上的任意点(x, y)所对应的矩阵坐标为(int(x/(3*LEN)), int(y/ (√3*LEN)))。
//wx,wy -> 表示纹理坐标在所对应的矩阵坐标为
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;