メインコンテンツまでスキップ

Filtered Cosine Wave Generator

Mathematical Foundation

The filtered cosine function transforms raw mathematical waves into visually refined patterns. Instead of harsh, jagged oscillations at high frequencies, this function automatically detects frequency density and gracefully fades intense variations to create smooth, elegant wave forms.

Filtered Cosine Formula: fcos(x)=cos(x)smoothstep(2π,0,fwidth(x))\text{fcos}(x) = \cos(x) \cdot \text{smoothstep}(2\pi, 0, \text{fwidth}(x))

Where:

  • cos(x)\cos(x) is the standard cosine function
  • fwidth(x)=xs+xt\text{fwidth}(x) = |\frac{\partial x}{\partial s}| + |\frac{\partial x}{\partial t}| measures the rate of change across pixels
  • smoothstep(a,b,x)=3t22t3\text{smoothstep}(a, b, x) = 3t^2 - 2t^3 where t=clamp(xaba,0,1)t = \text{clamp}\left(\frac{x-a}{b-a}, 0, 1\right)

The filtering multiplier becomes:

filter(x)={1if fwidth(x)0smoothstep(2π,0,fwidth(x))if 0<fwidth(x)<2π0if fwidth(x)2π\text{filter}(x) = \begin{cases} 1 & \text{if } \text{fwidth}(x) \leq 0 \\ \text{smoothstep}(2\pi, 0, \text{fwidth}(x)) & \text{if } 0 < \text{fwidth}(x) < 2\pi \\ 0 & \text{if } \text{fwidth}(x) \geq 2\pi \end{cases}

This automatically fades high-frequency oscillations to prevent aliasing artifacts.

This technique proves invaluable when creating procedural patterns, animated textures, and rhythmic visual effects where standard cosine functions would produce unwanted artifacts or visual noise.

ライブエディター
const fragment = () => {
      const coord = uv.mul(8)
      const wave1 = fcos(coord.x.mul(TWO_PI))
      const wave2 = fcos(coord.y.mul(TWO_PI))
      const combined = wave1.mul(wave2).add(1).div(2)
      return vec4(vec3(combined), 1)
}

Complex Wave Interference Patterns

Multiple filtered cosine waves can interact to create sophisticated interference patterns. The filtering prevents aliasing artifacts that would normally occur with rapidly oscillating wave combinations.

ライブエディター
const fragment = () => {
      const angle = uv.y.sub(0.5).atan2(uv.x.sub(0.5))
      const radius = uv.sub(0.5).length().mul(20)
      const ripple = fcos(radius.sub(iTime.mul(3)).mul(TWO_PI))
      const spiral = fcos(angle.mul(8).add(iTime).mul(TWO_PI))
      const pattern = ripple.mul(spiral).add(1).div(2)
      const hue = pattern.mul(0.8).add(0.1)
      return vec4(hue.mul(2), hue, hue.mul(1.5), 1)
}