이웃 격자 밖으로 출력된 결과에 대한 자연스러운 처리

  ..
  
  float n = Hash21(id);
  col += Star(gv - vec2(n, fract(n * 34.)) + .5, 1.);
  
  ..

위의 결과를 보면 격자 하나에 대해 어떤 형상 하나가 표시되어 있다. 문제는 형상 하나가 외부 격자 밖에서는 짤려나간다는 것인데, 이를 해결하기 위한 코드가 아래와 같다.

  ..
  
  for(int y=-1; y<=1; y++) {
      for(int x=-1; x<=1; x++) {
        vec2 offs = vec2(x, y);
        
        float n = Hash21(id + offs);
        col += Star(gv - offs - vec2(n, fract(n * 34.)) + .5, 1.);
      }
  }
  
  ..

위의 코드에서 유의해야할 점은 형상 하나가 바로 인접한 이웃의 이웃 밖으로 나갈 경우 처리되지 않는다. 이럴때는 밖으로 나간 것까지 포함되도록 for 문의 반복 범위를 확장해야 한다.

전체 코드는 다음과 같다.

uniform vec3 uResolution;
uniform float uTime;
uniform vec4 uMouse;

mat2 Rot(float a) {
  float s = sin(a);
  float c = cos(a);
  return mat2(c, -s, s, c);
}

float Star(vec2 uv, float flare) {
  float d = length(uv);
  float m = .05 / d;
  
  float rays = max(0., 1. - abs(uv.x * uv.y * 1000.));
  m += rays * flare;
  uv *= Rot(3.1415 / 4.); 
  rays = max(0., 1. - abs(uv.x * uv.y * 1000.));
  m += rays * .3 * flare;

  m *= smoothstep(1., .0, d); // 형상 하나가 바로 인접한 이웃 밖으로 나가지 않도록 해주는 코드

  return m; 
}

float Hash21(vec2 p) {
  p = fract(p * vec2(123.34, 456.21));
  p += dot(p, p + 45.32);
  return fract(p.x * p.y);
}

void main() {
  vec2 uv = (gl_FragCoord.xy - .5 * uResolution.xy) / uResolution.y;
  uv *= 3.;

  vec3 col = vec3(0);

  vec2 gv = fract(uv) - .5;
  vec2 id = floor(uv);

  for(int y=-1; y<=1; y++) {
      for(int x=-1; x<=1; x++) {
        vec2 offs = vec2(x, y);
        
        float n = Hash21(id + offs);
        col += Star(gv - offs - vec2(n, fract(n * 34.)) + .5, 1.);
      }
  }

  if(gv.x > .48 || gv.y > .48) col.r = 1.;  

  gl_FragColor = vec4(col, 1.0);
}

Mandelbrot Fractal

x축은 실수부, y축을 허수로 생각하는 공간(복소수평면)에서의 원점에서 일정한 offset 값만큼 이동하여 제곱한 값에 대한 실수부와 허수를 각각 x, y축으로 삼아 픽셀값으로 시각화한 결과가 Mandelbrot Fractal이며 구현 코드와 그에 대한 결과는 아래와 같다.

uniform vec3 uResolution;
uniform float uTime;
uniform vec4 uMouse;

void main() {
  vec2 uv = (gl_FragCoord.xy - .5 * uResolution.xy) / uResolution.y;
  uv += vec2(0.08, 0.15);
  vec2 c = uv * 2.5 + vec2(-.69955, -.37999); // Offset
  vec2 z = vec2(0.);
  float iter = 0.;
  float max_iter = 60.;

  float h = 2. + sin(uTime);
  for(float i=0.; i<max_iter; i++) {
    z = vec2(
      z.x * z.x - z.y * z.y, // 실수부
      2. * z.x * z.y // 허수부
    ) + c;
    if(length(z) > 2.) break;

    iter++;
  }

  float f = iter / max_iter;
  f = pow(f, .75);
  vec3 col = vec3(f);

  gl_FragColor = vec4(col, 1.0);
}