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)) ); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM