• 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)) 
                            );
        
    }
  • 相关阅读:
    Next.js文档自定义App、Document,getInitialProps翻译
    使用fetch进行数据请求时报json错误
    菜单制作:ul li横向排列
    Django Auth组件->扩展用户
    001.Django_Model.整理
    PyCharm中的django项目的引入
    Css3 里的弹性盒的比例关系
    vue的组件通讯 父传子 -- 子传父-- 兄弟组件的传值 vue的组件传值
    新手如何创建一个vue项目 ---vue---新手创建第一个项目
    如何自学计算机前端开发?精细的自学步骤是什么样的?
  • 原文地址:https://www.cnblogs.com/simonxia/p/4481551.html
Copyright © 2020-2023  润新知