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

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

如下图:

我们可以发现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. [置顶] Java套接字Socket编程

    1)概念 网络编程基本模型就客户端到服务器的模型,也就是我们常见的C/S模型.简单的说就是两个进程间相互通信的过程.即通信双方一方作为服务器等待客户端提出请求并给以回应,另一方作为客户端向服务器提出请 ...

  3. 分析一个socket通信: server/client

    分析一个socket通信: server/client1 server 1. 创建一个server_socket文件,并绑定端口,然后监听端口 (socket, bind, listen) 2. 查询 ...

  4. 闲扯 Javascript 04 滚动条

    物体运动基础 让Div移动起来 offsetLeft的作用 用定时器让物体连续移动 效果原理 让ul一直向左移动 复制li innerHTML和+= 修改ul的width 滚动过界后,重设位置 判断过 ...

  5. Oracle查看表空间使用情况

     查看表空间使用情况 select upper(f.tablespace_name) "表空间名",        d.tot_grootte_mb "表空间大小(m ...

  6. Android如何监听蓝牙耳机的按键事件

    写在前面: 直接想要代码很简单,你直接把滚动条拉到最底端就可以看到.如果想要十分地了解为什么,那就按照我规划的一步一步来理解.以下测试环境以手头上有的「Bluedio + 红米手机」. 1.蓝牙耳机的 ...

  7. Lucene4.3入门

    辞职交接期间无聊看了一下搜索引擎,java社区比较火的当然是Lucene,想写一个简单的小例子,在网上找了些资料,不过都不是4.3的,自己看了一下. 下载地址:http://lucene.apache ...

  8. Troubleshooting:oVirt-engine

    问题:执行./create_db_devel.sh -u postgres创建数据库时出错 描述: [root@localhost dbscripts]# ./create_db_devel.sh - ...

  9. Table中的JCheckBox TableHeader的全选(全反选)功能

    菜鸟学习ing class CheckDefaultModel extends DefaultTableModel /* * To change this template, choose Tools ...

  10. JSP简单练习-使用JDOM创建xml文件

    注意:在编写代码前,请确保该Web文件夹下的"WEB-INF/lib"下包括jdom.jar包! <%@ page language="java" con ...