不久前做了六边形马赛克的效果,很有意思,乘热打铁,弄了个三角形马赛克。

首先肯定是等边三角形,这样才能真正的无缝拼接。观察发现,三角形可以拼接成之前做个的六边形。

如下图:

我们可以发现6个三角形正好组成了一个六边形。

我们要判断一个点属于哪个三角形,必须先判断它属于那个六边形,这个在之前的博文中已经提到了。

OK,我们知道在那个六边形了,也就是我们知道了上面O点的坐标。我们开始想怎么判断它在哪个三角形。

嗯,我想大家都能想到,根据点与中心点O的夹角判断在那个三角形,调用atan就OK了:

float a = atan((x-O.x)/(y-O.y));//夹角

然后根据各自的角度就能判断是属于哪一个三角形的了,这里注意一下atan算出的范围是-180至180度,对应的数值是-PI至PI。

然后算出6个三角形的中心点坐标,属于哪一个三角形就去哪一个坐标点的像素值。

碎片着色器frag shader如下:

#version 400
#extension GL_ARB_texture_rectangle : enable uniform float len;
uniform sampler2DRect colorTex0;
void main (void){
float TR = 0.866025f;
float PI6 = 0.523599f; //PI/6
float x = gl_TexCoord[0].x;
float y = gl_TexCoord[0].y;
int wx = int(x/1.5f/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.5f*wx, len*TR*wy);
v2 = vec2(len*1.5f*(wx+1), len*TR*(wy+1));
} else {
v1 = vec2(len*1.5f*wx, len*TR*(wy+1));
v2 = vec2(len*1.5f*(wx+1), len*TR*wy);
}
} else {
if(wy/2 * 2 == wy) {
v1 = vec2(len*1.5f*wx, len*TR*(wy+1));
v2 = vec2(len*1.5f*(wx+1), len*TR*wy);
} else {
v1 = vec2(len*1.5f*wx, len*TR*wy);
v2 = vec2(len*1.5f*(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 = texture2DRect(colorTex0, 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/4);
vec2 area3 = vec2(vn.x+len/2, vn.y+len/TR/4);
vec2 area4 = vec2(vn.x, vn.y+len/TR/2);
vec2 area5 = vec2(vn.x-len/2, vn.y+len/TR/4);
vec2 area6 = vec2(vn.x-len/2, vn.y-len/TR/4);
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 = texture2DRect(colorTex0, vn);
gl_FragColor = color;
}

其中len为传入到shader中六边形的单边长,也是三角形的单边长。TR其实是√3/2。而PI6明显就是PI/6,对应的是30度。

其实核心思想就是判断属于哪个三角形。

效果如下:

同样的,实时改变len的值,图就能动起来:

依旧很炫,^_^.

openframeworks中主要代码:

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
img.loadImage("bg.jpg"); fbo.allocate(640, 480); shader.load("triangle.vert", "triangle.frag");
len = 100.0f;
bAdd = false;
} //--------------------------------------------------------------
void testApp::update(){
if(len < 10.0f)
bAdd = true;
if(len > 100.0f)
bAdd = false;
len += bAdd ? (0.05f):(-0.05f);
} //--------------------------------------------------------------
void testApp::draw(){
ofEnableAlphaBlending(); fbo.begin();
img.draw(0, 0, 640, 480);
fbo.end(); shader.begin();
shader.setUniform1f("len", len);
shader.setUniformTexture("colorTex0", fbo.getTextureReference(), 0);
fbo.draw(0, 0, 640, 480);
shader.end(); ofDisableAlphaBlending();
}

OK,有兴趣的可以试试。

『openframeworks』shader制作三角形马赛克效果的更多相关文章

  1. pixijs shader 制作百叶窗效果

    pixijs shader 制作百叶窗效果 直接贴代码了 const app = new PIXI.Application({ transparent: true }); document.body. ...

  2. CSS制作三角形和按钮

    CSS制作三角形和按钮 用上一篇博文中关于边框样式的知识点,能制作出三角形和按钮. 我先说如何制作三角形吧,相信大家在平时逛网站的时候都会看到一些导航栏中的三角形吧,比如说: 网易首页的头部菜单栏中, ...

  3. CSS 制作三角形原理剖析

    使用css制作三角形其实原理很简单,下面一步步解析. 1.html代码如下 <div class="triangle"> </div> 2.CSS代码 .t ...

  4. [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装

    [原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...

  5. canva实践小实例 —— 马赛克效果

    前面给大家带来了操作像素的API,此时此刻,我觉得应该配以小实例来进行进一步的说明和演示,以便给大家带来更宽广的视野和灵感,你们看了我的那么多的文章,应该是懂我的风格,废话不多说,进入正题: 这次给大 ...

  6. 用css制作三角形

    用css制作三角形,主要是利用css元素给“盒模型”设置边框得到的. 上图,上边框和做边框,以及上边框和右边框的交合处,浏览器会按照直角的二分之一处绘制交合线.这是“盒模型”有宽和高时候的效果.我们假 ...

  7. [C#]『CountdownEvent』任务并行库使用小计

    System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定. CountdownEvent  专门用于以下情况:您必须使用 ...

  8. 『转载』Debussy快速上手(Verdi相似)

    『转载』Debussy快速上手(Verdi相似) Debussy 是NOVAS Software, Inc(思源科技)发展的HDL Debug & Analysis tool,这套软体主要不是 ...

  9. 用border或者div制作三角形等图形

    一般情况下, 我们设置盒子的宽高度, 及上下左右边框, 具体代码如下: 通过上述代码,div的具体样式如下: 现在在上面基础上, 我们把div的宽高度都设为0时, 现在我们再次查看效果,如下图: 这时 ...

随机推荐

  1. 从陌陌上市看BAT的移动保卫战(转)

    12 月 11 日,陌陌正式登陆纳斯达克,这件事除了证明了移动互联网“没有什么不可能之外”,对 BAT 而言,更大的意义在于需要时刻警惕还有没有其它细分领域的公司能够在自己核心业务领域溜出来. 两年前 ...

  2. 快速傅里叶变换应用之二 hdu 4609 3-idiots

    快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...

  3. Qt调用DLL

    声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:   ...

  4. Qt国际化相关类(以前没见过codec->toUnicode,QTextCodec,QLocale.toString和QLocale::setDefault,QInputMethod::locale())

    QTextCodec QTextCodec为文本编码之间提供转换. Qt用Unicode 来存储,绘制和操作字符串.在很多情况下你可能希望操作不同编码的数据.例如,大部分日本文档是以Shift-JIS ...

  5. jsp各部分编码的含义

    服务器JSP编码 pageEncoding 是jsp文件本身的编码, 第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,(jsp文件的编码,pageEncoding是 ...

  6. 浅尝key-value数据库(二)——MongoDB的优与劣

    浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...

  7. ios网络学习------1get post异步请求

    网络请求的步骤: get请求: #pragma mark - 这是私有方法,尽量不要再方法中直接使用属性,由于一般来说属性都是和界面关联的,我们能够通过參数的方式来使用属性 #pragma mark ...

  8. QT之深入理解QThread

    QT之深入理解QThread       理解QThread之前需要了解下QThread类,QThread拥有的资源如下(摘录于QT 5.1 帮助文档):       在以上资源中,本文重点关注槽:s ...

  9. @produces在spring mvc中是什么意思

    @RequestMapping(value = "/produces", produces = "application/json"):表示将功能处理方法将生产 ...

  10. ssh安装过程

    1.在线安装[root@Asianux ~]# sudo apt-get install ssh   2.进行加密设置[root@Asianux ~]# ssh-keygen -t rsa3.启动SS ...