1. 程式人生 > >Shader特效——“Voronoi 影象”的實現 【GLSL】

Shader特效——“Voronoi 影象”的實現 【GLSL】

程式碼參考自inigo quilez老師的Shader Toy


延伸閱讀:

用GPU實現Cellular Texture 

iq老師的相關的三篇文章:

smooth voronoi 

voronoi lines 

voronoise 



效果圖



附上我的修改效果圖:





GLSL程式碼:

// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
uniform float iGlobalTime;
// 隨機方法
vec2 hash( vec2 p ) 
{ 
   p=vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); 
   
   return fract(sin(p)*18.5453);
}

// return distance, and cell id
vec2 voronoi( in vec2 x )
{
    vec2 n = floor( x );              // cell(n)
    vec2 f = fract( x );              // 當前畫素在cell space的座標

   vec3 m = vec3( 8. );               // 影響每個cell的大小,影響背景顏色
   
   // 遍歷相鄰的9個cell
    for( int j=-1; j<=1; j++ )
    {
       for( int i=-1; i<=1; i++ )
       {
           vec2  g = vec2( float(i), float(j) );  // 臨近的 cell id offset
           // n+g 臨近的 cell(n+g) 的隨機畫素座標 o (cell space)
           vec2  o = hash( n + g );   // 影響cell的顏色
           
           // ❤
           vec2  r = g - f + (0.5+0.5*sin(iGlobalTime+6.2831*o));
           //vec2  r = g - f + o;     // cell(n+g)[o] - cell(n)[f] 
          
           // ❤
           float d = dot( r, r );
 
           // 儲存更小的d
           if( d<m.x )
           {
              m = vec3( d, o );
           }
       }
    }
    return vec2( sqrt(m.x), m.y+m.z );
}

void main( )
{
   vec2 iResolution = vec2(512., 512.);
   vec2 p = gl_FragCoord.xy/max(iResolution.x,iResolution.y);
    
   // computer voronoi patterm
   vec2 c = voronoi( (14.0+6.0*sin(0.2*iGlobalTime))*p );
   
   // colorize
   vec3 col = 0.5 + 0.5*cos( c.y*6.2831 + vec3(0.0,1.0,2.0) ); // cell的隨機顏色
     
   col *= clamp(1.0 - 0.6*c.x*c.x, 0.0, 1.0);
   col -= (1.0-smoothstep( 0.05, 0.06, c.x));                  // 畫Voronoi的site點集
   
   gl_FragColor = vec4( col, 1.0 );
}