TouchDesigner中通过GLSL 把视频变成六角形、三角形和圆形的像素化效果

做的几个类似的滤镜实验,主要是想把普通的视频做成能有一些比较风格化的效果,参考了shadertoys里面的一些案例,然后在touchdesigner中分别实现了六角形、三角形和圆形的马赛克效果,如果再做一些颜色调整其实能达到比较有意思的互动效果。下面是效果图:

original

hexagon

circle

triangle

当然所有效果也都是实时的。

下面是代码:

HEXAGON,这个效果在搜寻最近六边形上有一个大神已经把算法做好了,直接照着他的用就好了:

http://www.gamedev.net/page/resources/_/technical/game-programming/coordinates-in-hexagon-based-tile-maps-r1800

layout(location = 0) out vec4 fragColor;
uniform float size;
uniform float edge;
uniform float samples;

const float PI = 3.14159265359;
const float TAU = 2.0*PI;
const float deg30 = TAU/12.0;

vec4 resolution = uTD2DInfos[0].res;

float hexDist(vec2 a, vec2 b){
    vec2 p = abs(b-a);
    float s = sin(deg30);
    float c = cos(deg30);

    float diagDist = s*p.x + c*p.y;
    return max(diagDist, p.x)/c;
}

vec2 nearestHex(float s, vec2 st){
    float h = sin(deg30)*s;
    float r = cos(deg30)*s;
    float b = s + 2.0*h;
    float a = 2.0*r;
    float m = h/r;

    vec2 sect = st/vec2(2.0*r, h+s);
    vec2 sectPxl = mod(st, vec2(2.0*r, h+s));

    float aSection = mod(floor(sect.y), 2.0);

    vec2 coord = floor(sect);
    if(aSection > 0.0){
        if(sectPxl.y < (h-sectPxl.x*m)){
            coord -= 1.0;
        }
        else if(sectPxl.y < (-h + sectPxl.x*m)){
            coord.y -= 1.0;
        }

    }
    else{
        if(sectPxl.x > r){
            if(sectPxl.y < (2.0*h - sectPxl.x * m)){
                coord.y -= 1.0;
            }
        }
        else{
            if(sectPxl.y < (sectPxl.x*m)){
                coord.y -= 1.0;
            }
            else{
                coord.x -= 1.0;
            }
        }
    }

    float xoff = mod(coord.y, 2.0)*r;
    return vec2(coord.x*2.0*r-xoff, coord.y*(h+s))+vec2(r*2.0, s);
}

vec4 sampleColor(vec2 position){

    vec2 hor = vec2(0.002, 0.0);
    vec2 ver = vec2(0.0, 0.002);
    int count = 0;
    vec3 amountColor = vec3(0.0);

    for(int i = 1; i <= samples; i++){
        vec2 tmpHor = hor * i;
        vec2 tmpVer = ver * i;

        amountColor += texture(sTD2DInputs[0], position - tmpHor).rgb +
                      texture(sTD2DInputs[0], position + tmpHor).rgb +
                      texture(sTD2DInputs[0], position - tmpVer).rgb +
                      texture(sTD2DInputs[0], position + tmpVer).rgb;
        count++;
    }

    amountColor /= (float(count) * 4.0);
    return vec4(amountColor, 1.0);
}

void main(){
    vec4 videoColor = texture(sTD2DInputs[0], vUV.st);
    vec2 nearest = nearestHex(size, resolution.zw*vUV.st);
    vec4 sampleColor = sampleColor(nearest/resolution.zw);
    float dist = hexDist(vUV.st * resolution.zw, nearest);

    float interior = 1.0 - smoothstep(size - edge, size, dist);

    fragColor = vec4(sampleColor.rgb*interior, 1.0);

}

CIRCLE

layout(location = 0) out vec4 fragColor;
uniform float size;
uniform float samples;
uniform float board;

const float PI = 3.14159265359;
const float TAU = 2.0*PI;
const float deg30 = TAU/12.0;

vec4 resolution = uTD2DInfos[0].res;

int cutEdge(float dist, float size){
    int flag;
    if(dist <= (size - board)/2.0){flag = 1;}
    else{flag = 0;}
    return flag;
}

vec4 filterColor(vec2 position){
    vec2 hor = vec2(0.001, 0.0);
    vec2 ver = vec2(0.0, 0.001);
    int count = 0;
    vec3 amountColor = vec3(0.0);

    for(int i = 1; i <= samples; i++){
        vec2 tmpHor = hor * i;
        vec2 tmpVer = ver * i;

        amountColor += texture(sTD2DInputs[0], position - tmpHor).rgb +
                      texture(sTD2DInputs[0], position + tmpHor).rgb +
                      texture(sTD2DInputs[0], position - tmpVer).rgb +
                      texture(sTD2DInputs[0], position + tmpVer).rgb;
        count++;
    }

    amountColor /= (float(count) * 4.0);
    return vec4(amountColor, 1.0);
}

vec2 nearestCenter(float size, vec2 st){
    vec2 currentPos = st * resolution.zw;

    //find the unit
    vec2 unit = floor(currentPos / vec2(size));
    return unit * size + vec2(size/2.0);
}

void main(){
    vec4 videoColor = texture(sTD2DInputs[0], vUV.st);
    vec2 nearCenter = nearestCenter(size, vUV.st);
    vec4 sampleColor = filterColor(nearCenter / resolution.zw);

    float dist = distance(nearCenter, vUV.st * resolution.zw);

    int interior = cutEdge(dist, size);

    fragColor = vec4(sampleColor.rgb * interior, 1.0);
    //fragColor = vec4(vec3(interior), 1.0);
}

TRIANGLE

这一个效果直接是抄的一个大神的算法,妈的真是神了,简单一行就定义好了图像采样的方法,给大家看后反馈的结果还TM是最好的。真不知道这些神一样存在的人脑袋里面都装了一些什么.....

layout(location = 0) out vec4 fragColor;
uniform vec2 tile_num;

void main(){
    vec2 uv = vUV.st;
    vec2 uv2 = floor(uv*tile_num)/tile_num;
    uv -= uv2;
    uv *= tile_num;

    fragColor = texture(sTD2DInputs[0],
                        uv2 + vec2(step(1.0-uv.y,uv.x)/(2.0*tile_num.x),step(uv.x,uv.y)/(2.0*tile_num.y))
                        );

}
时间: 2024-11-18 07:07:39

TouchDesigner中通过GLSL 把视频变成六角形、三角形和圆形的像素化效果的相关文章

Houdini和Touchdesigner中实现场力与弹力的相互作用

最近一直在研究怎样怎样将程序化特效和动画从houdini中转移到touchdesigner中,前段时间拿着了leapmotion做开发,自己一个人自娱自乐也快玩疯了. 今天讲一讲从法国一个虚拟交互舞团某个场景中得到灵感,设计一个简单的通过斥力和弹力混合出来的平衡场效果. 首先看一看人家在舞台上达到的是个什么效果: 在应用之前,先讲一讲我通过这个视频看到的原理. 人物的运动提供了一个位置信息P,也许群体运动的那个画面中提取了运动的速度或者加速信息,这里先不做复杂的讨论.画面中的每个点pt与上述提供

在Windows Server 2008 R2 Server中,上传视频遇到的问题(二)

上一篇  在Windows Server 2008 R2 Server中,上传视频遇到的问题(一)中遇到上传40M视频报404,然后修改配置文件节点: <httpRuntime targetFramework="4.5.2" maxRequestLength="1073741824" executionTimeout="3600"/> 和 <security> <requestFiltering> <!-

实验6 在应用程序中播放音频和视频

实验报告 课程名称 基于Android平台移动互联网开发 实验日期 4月15日 实验项目名称 在应用程序中播放音频和视频 实验地点 S3002 实验类型 □验证型    √设计型    □综合型 学  时 一.实验目的及要求(本实验所涉及并要求掌握的知识点) 实现在应用程序中处理音频和视频. [要求] 1) 实现播放音频,音频播放控制: 2) 实现播放视频,视频播放控制: 3) 使用Service服务播放项目源文件中的音乐. 二.实验环境(本实验所使用的硬件设备和相关软件) (1)PC机 (2)

实验六 在应用程序中播放音频和视频

实验报告 课程名称 基于Android平台移动互联网开发 实验日期 2016年4月15日 实验项目名称 在应用程序中播放音频和视频 实验地点 S30010 实验类型 □验证型    √设计型    □综合型 学  时 2 一.实验目的及要求(本实验所涉及并要求掌握的知识点) 1.实现在应用程序中处理音频和视频. 2.实现播放音频,音频播放控制: 3. 实现播放视频,视频播放控制: 4. 使用Service服务播放项目源文件中的音乐. 二.实验环境(本实验所使用的硬件设备和相关软件) (1)PC机

embed标签的使用(在网页中播放各种音频视频的插件的使用)

embed标签的使用(在网页中播放各种音频视频的插件的使用) 链接地址:http://blog.csdn.net/TomyGuan/archive/2006/11/10/1377807.aspx 播放器插件使用说明: 代码:< EMBED src="music.mid"autostart="true"loop="2"width="80"height="30"> src:音乐文件的路径及文件名:(

对于微信内置浏览器中不能小窗播放视频原因的分析以及解决

菜鸟:微信内置浏览器中不能小窗播放视频肿么办??? 师傅:徒弟莫猴急,待师傅一一道来:首先,喺发生急事嘅情况下,我哋最要保持冷静,噉才可以施展出一个有思维.有智慧.有头脑嘅人,应该有嘅气质与才华. 菜鸟:哇,知啦,跟住我应该点做哩? 师傅:求百度啊!!!!!! ......以上是背景......以下是根据百度爬到的内容进行的分析与总结...... 分析webkit-playsinline为什么不能在微信内核中起作用的原因: 1:在不考虑微信内核的浏览器中用html5的video方式播放视频时:在

《SEO在网页制作中的应用》视频笔记

学习了慕课网<SEO在网页制作中的应用>视频,今天将里面的知识整理一下. 一.SEO介绍 1.  搜索引擎工作原理 搜索引擎现在主流有百度.谷歌.360,他们都有庞大的搜索引擎数据库,每个关键字对应很多网址,搜索引擎爬虫从一个链接到另一个链接,分析提炼其中的内容,找到关键字,如果是重要的或是首次出现的内容,就会添加到搜索引擎数据库,如果是垃圾内容或是重复内日你给,爬虫就会略过.当用户(比如在百度)搜索信息时,搜索引擎就从数据库检索出与之相关的网址,然后展示给用户,因为一个关键字可以对应很多网址

在ASP.NET中实现图片、视频文件上传方式

一.图片 1.在前端用<asp:FileUpload ID="UpImgName" runat="server"/>控件 2.在后台.cs中写上 protected void btnSubmit_Click(object sender,EventArgs e) { string strImgPath=string.Empty; string strDateTime=dateTime.Now.Tostring("yyyyMMddhhmmss&qu

整理了一些.NET中的方案应用视频给大家

1.方案:ASP.NET开发RSS新闻发布订阅技术方案 http://edu.ibeifeng.com/view-index-id-162.html 2.方案:ASP.NET开发在线编辑器模块技术方案 http://edu.ibeifeng.com/view-index-id-161.html 3.方案:如何操作Excel文件带项目 http://edu.ibeifeng.com/view-index-id-159.html 4.方案:如何以流式方式读写文本文件 http://edu.ibeif