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

摘要:
常量浮动TAU=2.0*PI;vec4resolution=uTD2DInfos[0].res;浮动系数=2.0*r;vec2coord=地板(截面);(sectPxl.x*m)){coord.y-=1.0;intcount=0;vec3amountColor=vec3(0.0);=样本;}amountColor/=(float(计数)*4.0);

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

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

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

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

TouchDesigner中通过GLSL 把视频变成六角形、三角形和圆形的像素化效果第4张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)) 
                        );
    
}

免责声明:文章转载自《TouchDesigner中通过GLSL 把视频变成六角形、三角形和圆形的像素化效果》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇常见局域网类别PHP条件语句if的使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

c++ string 的函数replace()用法

basic_string::replace 将原string 中的元素或子串替换。返回替换后的string。 (1)用string 或C-string 代替操作string 中从 _Pos1 开始的 _Num1 个字符 basic _ string& replace( size _ type _Pos1 ,size _ type _Num1 ,...

jQuery Easing 动画效果扩展--使用Easing插件,让你的动画更具美感。

jQuery  Easing 是一款比较老的jQuery插件,在很多网站都有应用,尤其是在一些页面滚动、幻灯片切换等场景应用比较多。它非常小巧,且有多种动画方案供选择,使用简单,而且免费。 引入Easing js文件 该插件基于jQuery,所以需要同时引入jQuery库文件和Easing js文件。 <script type="text/javas...

实现自定义的小程序底部tabbar

背景 诶,当然是为了实现更有温度的代码啦(背后设计师拿着刀对着我) 自带tabbar app.json中配置: tabBar: { backgroundColor: '#fff', borderStyle: 'white', color: '#333', selectedColor: '#333', list: [ {...

python中filter()函数

filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。 例如,要从一个list [1, 4, 6, 7, 9, 12, 17]中...

python 之 数据类型初接触

python 之 数据类型初接触 标准数据类型 Python3 中有六个标准的数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Set(集合) Dictionary(字典) Python3 的六个标准数据类型中: 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);...

Python接口自动化(五) cookie绕过验证码登录

有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接)。获取不到也没关系,可以通过添加cookie的方式绕过验证码。 抓登录cookie 如博客园,未登录时,使用fiddler抓包查看cookie值。登录后,使用fiddler抓包查看cookie值。查看cookie变化,发现多个两组参数。 #c...