Shader特效——“马赛克”的实现【GLSL】
来源:互联网 发布:怎么使用java 编辑:程序博客网 时间:2024/05/01 23:39
参考自:http://tech.it168.com/n/2007-03-29/200703291522292_3.shtml 和 http://blog.csdn.net/simpledrunk/article/details/17170965
原图:
”圆形” 效果图1 :
“圆形”效果2:
片元着色器代码:
uniform sampler2D Texture0;const vec2 texSize = vec2(640., 640.);const vec2 mosaicSize = vec2(8., 8.);varying vec2 vUV;void main(void){ vec2 xy = vec2(vUV.x * texSize.x, vUV.y * texSize.y);// 取值范围换算到图像尺寸大小 // 计算某一个小mosaic的中心坐标 vec2 xyMosaic = vec2(floor(xy.x / mosaicSize.x) * mosaicSize.x, floor(xy.y / mosaicSize.y) * mosaicSize.y ) + .5*mosaicSize; // 计算距离中心的长度 vec2 delXY = xyMosaic - xy; float delL = length(delXY); // 换算回纹理坐标系 vec2 uvMosaic = vec2(xyMosaic.x / texSize.x, xyMosaic.y / texSize.y); vec4 finalColor; if(delL<0.5*mosaicSize.x) { finalColor = texture2D(Texture0, uvMosaic); } else { //finalColor = texture2D(Texture0, vUV); finalColor = vec4(0., 0., 0., 1.); } gl_FragColor = finalColor;}
“方形” 效果图:
片元着色器代码:
uniform sampler2D Texture0;const vec2 texSize = vec2(640., 640.);const vec2 mosaicSize = vec2(8., 8.);varying vec2 vUV;void main(void){ vec4 color; //float ratio = texSize.y/texSize.x; vec2 xy = vec2(vUV.x * texSize.x /** ratio */, vUV.y * texSize.y); vec2 xyMosaic = vec2(floor(xy.x / mosaicSize.x) * mosaicSize.x, floor(xy.y / mosaicSize.y) * mosaicSize.y ); //第几块mosaic vec2 xyFloor = vec2(floor(mod(xy.x, mosaicSize.x)), floor(mod(xy.y, mosaicSize.y))); #if 0 if((xyFloor.x == 0 || xyFloor.y == 0)) { color = vec4(1., 1., 1., 1.); } else #endif { vec2 uvMosaic = vec2(xyMosaic.x / texSize.x, xyMosaic.y / texSize.y); color = texture2D( Texture0, uvMosaic ); } gl_FragColor = color;}
“六边形” 效果图:
片元着色器代码:
uniform float Time_x;uniform sampler2D Texture0;varying vec2 vUV;uniform float len;void main (void){ float TR = 0.866025; float x = vUV.x; float y = vUV.y; int wx = int(x/1.5/len); int wy = int(y/TR/len); vec2 v1, v2, vn; if(wx/2 * 2 == wx) { if(wy/2 * 2 == wy) { v1 = vec2(len*1.5*wx, len*TR*wy); v2 = vec2(len*1.5*(wx+1), len*TR*(wy+1)); } else { v1 = vec2(len*1.5*wx, len*TR*(wy+1)); v2 = vec2(len*1.5*(wx+1), len*TR*wy); } } else { if(wy/2 * 2 == wy) { v1 = vec2(len*1.5*wx, len*TR*(wy+1)); v2 = vec2(len*1.5*(wx+1), len*TR*wy); } else { v1 = vec2(len*1.5*wx, len*TR*wy); v2 = vec2(len*1.5*(wx+1), len*TR*(wy+1)); } } float s1 = sqrt( pow(v1.x-x, 2) + pow(v1.y-y, 2) ); float s2 = sqrt( pow(v2.x-x, 2) + pow(v2.y-y, 2) ); if(s1 < s2) vn = v1; else vn = v2; vec4 color = texture2D(Texture0, vn); gl_FragColor = color;}
“三角形” 效果图:
片元着色器代码:
varying vec2 vUV;uniform sampler2D Texture0;// len 是六边形的边长uniform float len;void main (void){ const float TR = 0.866025; // .5*(3)^.5 const float PI6 = 0.523599; // PI/6 float x = vUV.x; float y = vUV.y; // 1.5*len 是矩形矩阵的长,TR*len 是宽 // ::计算矩形矩阵的顶点坐标 (0,0)(0,1)(1,0)(1,1) int wx = int(x/(1.5*len)); int wy = int(y/(TR*len)); vec2 v1, v2, vn; // 判断是矩形的哪个顶点,上半部还是下半部 if(wx/2 * 2. == wx) { if(wy/2 * 2. == wy) { // left top // 选择位于六边形中心的纹素作为颜色参考:左上右下 v1 = vec2(len*1.5*wx, len*TR*wy); v2 = vec2(len*1.5*(wx+1), len*TR*(wy+1)); } else { // left bottom // 左下右上 v1 = vec2(len*1.5*wx, len*TR*(wy+1)); v2 = vec2(len*1.5*(wx+1), len*TR*wy); } } else { if(wy/2 * 2. == wy) { // right top // 左下右上 v1 = vec2(len*1.5*wx, len*TR*(wy+1)); v2 = vec2(len*1.5*(wx+1), len*TR*wy); } else { // right bottom // 左上右下 v1 = vec2(len*1.5*wx, len*TR*wy); v2 = vec2(len*1.5*(wx+1), len*TR*(wy+1)); } } // 计算参考点与当前纹素的距离 float s1 = sqrt( pow(v1.x-x, 2.) + pow(v1.y-y, 2.) ); float s2 = sqrt( pow(v2.x-x, 2.) + pow(v2.y-y, 2.) ); // 选择距离小的参考点 if(s1 < s2) vn = v1; else vn = v2; vec4 mid = texture2D(Texture0, vn); float a = atan((x-vn.x)/(y-vn.y));// 计算夹角 // 分别计算六个三角形的中心点坐标,之后将作为参考点 vec2 area1 = vec2(vn.x, vn.y-len*TR/2.); vec2 area2 = vec2(vn.x+len/2., vn.y-len*TR/2.); vec2 area3 = vec2(vn.x+len/2., vn.y+len*TR/2.); vec2 area4 = vec2(vn.x, vn.y+len*TR/2.); vec2 area5 = vec2(vn.x-len/2., vn.y+len*TR/2.); vec2 area6 = vec2(vn.x-len/2., vn.y-len*TR/2.); // 根据夹角判断是哪个三角形 if(a >= PI6 && a < PI6*3.) vn = area1; else if(a>=PI6*3. && a<PI6*5.) vn = area2; else if((a>=PI6*5. && a<=PI6*6.) || (a<-PI6*5. && a>-PI6*6.)) vn = area3; else if(a<-PI6*3. && a>=-PI6*5.) vn = area4; else if(a<=-PI6 && a>-PI6*3.) vn = area5; else if(a>-PI6 && a<PI6) vn = area6; vec4 color = texture2D(Texture0, vn); gl_FragColor = color;}
另附其他效果:
0 0
- Shader特效——“马赛克”的实现【GLSL】
- Shader特效——实现“火苗”【GLSL】
- Shader特效——实现“闪电”【GLSL】
- Shader特效——实现“羽化”【GLSL】
- Shader特效——“水彩画”的实现【GLSL】
- Shader特效——实现简单的“FishEye”【GLSL】
- Shader特效——“Kuwahara Filter”的实现 【OpenCV】【GLSL】
- Shader特效——“Bilateral Filter”的实现 【GLSL】
- Shader特效——“Barrel Blur”的实现 【GLSL】
- Shader特效——“Canny边缘检测”的实现 【GLSL】
- Shader特效——“Gamma校正”的实现 【GLSL】
- Shader特效——“径向模糊”的实现 【GLSL】
- Shader特效——“翻页”的实现 【GLSL】
- Shader特效——“Voronoi 图像”的实现 【GLSL】
- Shader特效——“Sephia等效果”的实现 【GLSL】
- Shader特效——“Simple RayTrace”的实现 【GLSL】
- Shader特效——“Point in Box”的实现 【GLSL】
- Shader特效——“帧动画效果”的实现 【GLSL】
- 快速排序和冒泡排序
- tyvj 1415 西瓜种植
- 109.leetcode Convert Sorted List to Binary Search Tree(medium)[链表 平衡二叉搜索树 二分查找]
- Medium of Two Sorted Arrays
- 全角转半角/半角转全角(Python)
- Shader特效——“马赛克”的实现【GLSL】
- 指针的理解
- C语言之结构体 现有36名教师,每个教师包括教工号,姓名,工资共三项基本信息,请用C语言编程,从键盘上输入每一位教师的基本信息,并打印输出工资最高者的工号,姓名工资和所有教师的平均工资
- IOS-多线程(非常全面)
- 二维码的扫描
- Java和C++在编译和运行上有什么区别?
- 串口编程及其相关协议
- 访问权限问题
- 5、并发编程的3个概念:原子性、可见性、有序性