前言

我常常被問到:「我想學創意編程(Creative Coding),應該用什麼工具?」這個問題沒有標準答案,因為這個領域的工具鏈在過去二十多年裡不斷演化,每一代工具都有它獨特的定位和優勢。

從 2001 年 Processing 在 MIT Media Lab 誕生,到 2014 年 p5.js 讓瀏覽器成為創作畫布,再到 GLSL shader 直接在 GPU 上作畫——這是一段從「降低程式門檻」到「追求極致效能與表現力」的演化史。

這篇文章會帶你走一遍這段歷程,比較各工具的特點,幫你找到最適合自己的創作工具。

Processing:創意編程的開山鼻祖

誕生背景

2001 年,Casey Reas 和 Ben Fry 在 MIT Media Lab 的 Aesthetics + Computation Group(由 John Maeda 領導)創造了 Processing。他們的初衷很明確:讓藝術家和設計師也能用程式來創作

在當時,如果你想用程式碼畫東西,你得和 OpenGL 的 C/C++ API 搏鬥,或者用 Java 的 AWT/Swing——這對非程式背景的人來說簡直是噩夢。Processing 做了一件很了不起的事:它把「在螢幕上畫東西」這件事簡化到了極致。

核心設計理念

Processing 的程式結構建立在兩個函數上:

void setup() {
  size(800, 600);
  background(0);
}

void draw() { // 每幀被呼叫一次 ellipse(mouseX, mouseY, 50, 50); }

setup() 跑一次做初始化,draw() 每秒跑 60 次做繪圖。就這麼簡單。不需要理解 main function、事件迴圈、視窗管理——所有的複雜性都被藏在底層。

Processing 的影響

Processing 的影響遠超出工具本身:

  • 教育:全世界數百所大學把 Processing 用於程式設計入門課程。它證明了「用視覺回饋來學程式」是有效的。
  • 藝術:催生了「生成式藝術」(Generative Art)的蓬勃發展。無數藝術家用 Processing 創作展覽作品。
  • 社群:Processing Foundation 是一個非營利組織,致力於讓程式設計更具包容性。OpenProcessing 等平台讓全球的創作者可以分享作品。
  • 衍生工具:Processing 的理念啟發了一大批後續工具。

Processing 的局限

到了 2010 年代,Processing(基於 Java)的局限逐漸顯現:

  1. 需要安裝 JRE:分享作品不方便,接收者也得安裝 Java
  2. 桌面限定:在行動裝置和網頁上無法直接運行
  3. Java 語法:對完全的初學者來說,型別宣告、分號、大括號還是有門檻
  4. 效能上限:雖然可以呼叫 OpenGL,但架構上不如原生 C++

p5.js:Processing 的 Web 轉生

誕生

2014 年,Lauren Lee McCarthy 創造了 p5.js——Processing 理念的 JavaScript 實現。這不是把 Processing 翻譯成 JavaScript 那麼簡單,而是一次深思熟慮的重新設計。

p5.js 的口號很棒:“p5.js is for everyone.” 它特別強調包容性——不只是技術上的低門檻,還包括文件的多語言化、對身心障礙者的可及性支援等。

p5.js vs Processing

// p5.js — 和 Processing 幾乎一模一樣的結構
function setup() {
  createCanvas(800, 600);
  background(0);
}

function draw() { ellipse(mouseX, mouseY, 50, 50); }

主要差異:

  • 語言:JavaScript(動態型別、不需要分號、函數是一等公民)
  • 平台:在瀏覽器中運行,任何裝置都能看
  • 分享:一個 URL 就能分享作品(p5.js Web Editor)
  • 生態系:可以輕鬆整合 HTML/CSS、Web API(攝影機、麥克風、MIDI…)
  • DOM 互動:可以加入 HTML 元素(滑桿、按鈕、輸入框)

p5.js 的獨特優勢

Web Editor

p5.js 有一個非常好用的線上編輯器(editor.p5js.org),打開瀏覽器就能開始創作,不需要安裝任何東西。這對教學來說是殺手級的特性。

豐富的附加庫

// p5.sound — 音訊
let fft = new p5.FFT();
let spectrum = fft.analyze();

// p5.dom — HTML 元素互動(已內建) let slider = createSlider(0, 255, 127);

// ml5.js — 機器學習 let classifier = ml5.imageClassifier('MobileNet');

// matter.js — 物理模擬 // tone.js — 合成器 // ... 數十個社群庫

實例模式

// 在同一頁面放多個 p5 canvas
const sketch1 = (p) => {
  p.setup = () => {
    p.createCanvas(300, 300);
  };
  p.draw = () => {
    p.background(51);
    p.ellipse(p.mouseX, p.mouseY, 50, 50);
  };
};

const sketch2 = (p) => { p.setup = () => { p.createCanvas(300, 300); }; p.draw = () => { p.background(200, 50, 50); p.rect(p.mouseX, p.mouseY, 50, 50); }; };

new p5(sketch1, 'container1'); new p5(sketch2, 'container2');

p5.js 的局限

  1. 效能:JavaScript 在 CPU 密集運算上不如 Java/C++,更遠不如 GPU
  2. 像素操作慢loadPixels() + 逐像素計算在高解析度下很吃力
  3. 沒有多執行緒:Web Worker 可以幫忙,但整合不夠方便
  4. 2D 為主:雖然有 WEBGL 模式,但 3D 能力比專業 3D 框架弱

GLSL Shader:直接和 GPU 對話

為什麼需要 Shader?

當你在 p5.js 中對每個像素做計算(比如碎形、Voronoi、反應擴散),你會發現效能瓶頸來得很快。一個 800×800 的畫布有 64 萬個像素,每個像素要做幾十次浮點運算,全部交給 CPU 的一個核心——太慢了。

GPU 就是為了這種「大量獨立的平行計算」而生的。一個中階 GPU 有幾千個核心,可以同時計算所有像素。Shader(著色器)就是你寫給 GPU 執行的程式。

GLSL 基礎

GLSL(OpenGL Shading Language)是最通用的 shader 語言。在 WebGL 中使用的是 GLSL ES。

一個最基本的 fragment shader:

precision mediump float;

uniform vec2 u_resolution; // 畫布大小 uniform float u_time; // 時間

void main() { // 正規化座標到 [0, 1] vec2 uv = gl_FragCoord.xy / u_resolution;

// 一個簡單的漸層 vec3 color = vec3(uv.x, uv.y, abs(sin(u_time)));

gl_FragColor = vec4(color, 1.0); }

每個像素都會獨立執行一次 main() 函數。你不能存取「隔壁像素」的計算結果(除非透過紋理),你也不能在像素之間共享狀態。這種限制反而成了一種創作的獨特思維方式。

在 p5.js 中使用 Shader

let myShader;

function preload() { myShader = loadShader('shader.vert', 'shader.frag'); }

function setup() { createCanvas(800, 800, WEBGL); noStroke(); }

function draw() { shader(myShader); myShader.setUniform('u_resolution', [width, height]); myShader.setUniform('u_time', millis() / 1000.0); myShader.setUniform('u_mouse', [mouseX / width, mouseY / height]);

// 畫一個覆蓋全畫面的矩形,讓 shader 在上面運行 rect(0, 0, width, height); }

Shadertoy:Shader 的遊樂場

Shadertoy(shadertoy.com)是全世界最大的 shader 分享平台,由 Inigo Quilez 和 Pol Jeremias 創建。在上面你可以看到令人難以置信的作品——完全用數學公式即時渲染的 3D 場景、流體模擬、光線追蹤。

Shadertoy 的 shader 格式稍有不同,但核心相同:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;

vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));

fragColor = vec4(col, 1.0); }

GLSL 的學習曲線

GLSL 的思維方式和一般程式設計很不一樣:

  1. 沒有迴圈跑像素:你不是「一個一個畫像素」,而是「定義每個像素的顏色」
  2. 沒有狀態:每個像素的計算是獨立的,不能讀取其他像素的結果
  3. 數學密集:很多效果需要靠向量數學、距離函數、噪聲函數等技巧
  4. 除錯困難:沒有 console.log,只能靠「把值映射成顏色」來觀察

但一旦你適應了這種思維,GLSL 會打開一個全新的創作世界。

其他重要工具

TouchDesigner

TouchDesigner 是 Derivative 公司開發的視覺化程式設計環境,專攻即時視覺(real-time visuals)。它使用節點式(node-based)的介面,你透過連接不同功能的節點來建構視覺管線。

適合場景

  • 現場演出的 VJ 視覺
  • 互動裝置藝術(結合感測器、Kinect、MIDI 控制器)
  • 投影映射(Projection Mapping)
  • 即時生成式視覺

特色

  • 內建 GPU 加速的粒子系統、流體模擬
  • 可以直接寫 GLSL 和 Python
  • 支援多螢幕輸出、Spout/Syphon/NDI
  • 社群版(非商業用)免費

不足

  • 只有 Windows 和 macOS
  • 學習曲線陡峭
  • 商業授權昂貴
  • 不方便做網頁分享

cables.gl

cables.gl 是一個基於瀏覽器的視覺化程式設計工具,由 undev 團隊開發。它和 TouchDesigner 一樣使用節點式介面,但完全在 WebGL 上運行。

適合場景

  • 互動式網頁視覺
  • WebGL 學習(可以看到底層的 GL 操作)
  • 快速原型設計

特色

  • 完全在瀏覽器中運行,不需安裝
  • 可以匯出獨立的 WebGL 應用
  • 可以寫自訂 GLSL 節點
  • 社群分享方便

three.js 與 WebGL 框架

如果你想做更複雜的 3D 互動內容,three.js 是 WebGL 生態系統中最流行的框架:

// three.js 基本結構
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();

const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.ShaderMaterial({ vertexShader: vertexCode, fragmentShader: fragmentCode, uniforms: { u_time: { value: 0.0 } } });

const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);

function animate() { requestAnimationFrame(animate); material.uniforms.u_time.value = performance.now() / 1000; renderer.render(scene, camera); } animate();

three.js 是 p5.js WEBGL 模式和原始 WebGL 之間的甜蜜點——比 p5.js 靈活得多,但比原始 WebGL 友善得多。

其他值得一提的工具

  • openFrameworks:C++ 的創意編程框架,效能最強,適合硬體互動和大型裝置
  • Cinder:另一個 C++ 框架,API 更現代
  • nannou:Rust 的創意編程框架,型別安全 + 高效能
  • Hydra:即時 shader 編碼,專為 VJ 和 live coding 設計
  • Sonic Pi:音樂的創意編程工具(Ruby-based)
  • Unity/Unreal:遊戲引擎,越來越多藝術家用它做互動裝置

選擇地圖:我該用什麼?

| 需求 | 推薦工具 |
|——|———|
| 剛開始學程式 | p5.js |
| 教小朋友/工作坊 | p5.js Web Editor |
| 做網頁互動作品 | p5.js / three.js |
| 追求像素級的視覺效果 | GLSL (Shadertoy) |
| 做即時演出 VJ | TouchDesigner / Hydra |
| 做大型互動裝置 | openFrameworks / TouchDesigner |
| 做數學教學影片 | Manim |
| 做 3D 互動網站 | three.js / cables.gl |
| 做生成式 NFT 藝術 | p5.js / GLSL |
| 學習圖形學原理 | GLSL + 手寫 WebGL |

我的個人建議

如果你是初學者,從 p5.js 開始。它的學習曲線最平緩,社群最活躍,文件最完善。等你在 p5.js 中遇到效能瓶頸(通常是想做像素級的效果時),自然就會開始學 GLSL

如果你已經有程式基礎,直接從 The Book of Shaders 開始學 GLSL 也很好。它會徹底改變你思考圖形的方式。

如果你想做互動裝置或現場演出,TouchDesigner 是行業標準。它的節點式工作流程非常適合快速迭代和即時調整。

最後,不要被工具困住。創意編程的核心不是工具,而是 「用計算思維來表達美」 的能力。這種能力是可以跨工具遷移的。一旦你理解了正弦波、噪聲、距離場、矩陣變換這些基本概念,無論用什麼工具都能快速上手。

小結

從 Processing 到 p5.js 到 GLSL,創意編程工具的演化不是「新工具取代舊工具」的線性過程,而是一棵不斷分枝的大樹。每一個工具都在特定的生態位上繁盛:Processing 在教育和社群中根基深厚,p5.js 讓網頁成為最開放的創作平台,GLSL 讓 GPU 的平行算力為藝術家所用,TouchDesigner 統治了即時演出的世界。

我相信這棵樹還會繼續生長。WebGPU 正在取代 WebGL,AI 輔助生成正在改變創作流程,AR/VR 正在拓展「畫布」的定義。但不管工具怎麼變,那個最初的衝動——「我想用程式碼畫出美麗的東西」——永遠不會改變。

延伸閱讀

  • 《Processing: A Programming Handbook for Visual Designers and Artists》— Casey Reas & Ben Fry
  • The Coding Train (YouTube) — Daniel Shiffman 的 p5.js 教學頻道
  • The Book of Shaders — Patricio Gonzalez Vivo(thebookofshaders.com)
  • Inigo Quilez 的部落格(iquilezles.org)— shader 技術的百科全書
  • Creative Applications Network (creativeapplications.net) — 互動藝術作品報導
  • 嘗試在三種不同的工具中做同一個作品(例如粒子系統),比較體驗的差異