TSLとは?WebGPU時代の新しいシェーダーの書き方

約8分
TSLとは?WebGPU時代の新しいシェーダーの書き方

みなさんこんにちは。フロントエンドエンジニアのしゅん(@shun_webdesign)です。

最近、僕はXでThree.jsのシェーダー作品をちょこちょこ投稿しているんですが、その多くを「TSL」というもので書いています。

TSL=Three.js Shading Language。ここ最近のThree.jsで使えるようになった、新しいシェーダーの書き方です。

正直、最初は「GLSLで困ってないし、わざわざ新しいの覚える必要ある?」と思っていました。でも実際に触ってみると、これがWebGPU時代のスタンダードになるのも納得、という体験だったんですよね。

この記事では、そもそもTSLって何? なぜ今これなの? というところを、GLSLと見比べながらできるだけやさしく解説していきます。

その前に:WebGPUって何だっけ

TSLの話をする前に、背景にある「WebGPU」に軽く触れておきます。

ざっくり言うと、WebGPUはWebGLの後継にあたる、ブラウザでGPUを扱うための新しい仕組みです。2026年に入って主要ブラウザすべてで標準搭載になり、「実験的なもの」から「普通に使えるもの」になりました。

ここで地味に困るのが、シェーダー言語が変わるという点です。WebGLでは「GLSL」を書いていましたが、WebGPUでは「WGSL」という別の言語を書く必要があります。

つまり、WebGLとWebGPUの両方に対応しようとすると、同じ処理をGLSLとWGSLで二重に書くことになりかねない。これはなかなかしんどいですよね。

この「二重に書く問題」を解決してくれるのがTSLです。

TSLとは:JavaScriptでシェーダーを書く

TSL(Three.js Shading Language)の一番のポイントはこれです。

JavaScriptでシェーダーのロジックを書くと、Three.jsがそれをWGSL(WebGPU用)やGLSL(WebGL用)に自動で変換してくれる

GLSLやWGSLのような「文字列の言語」を直接書くのではなく、JavaScriptの関数やノードを組み合わせてシェーダーを表現する——というのがTSLの考え方です。書いたものは出力先に応じてコンパイルされるので、1回書けばWebGPUにもWebGLにも対応できるんですね。

僕がTSLに「なるほど」と思ったのは、まさにここでした。WebGPUへの移行を、シェーダーの書き直しなしで乗り越えられる道があるんだ、と。

GLSLのつらみと、TSLが嬉しい理由

これまでThree.jsでシェーダーを書くときは、ShaderMaterial にGLSLを文字列で渡していました。これ、慣れると書けるんですが、地味なつらみがあります。

  • ただの文字列なので、補完も型チェックも効かない(タイポに気づきにくい)
  • JS側の値とのやり取りがuniform経由で面倒
  • 処理を部品化して使い回しにくい

TSLはこのあたりが素直に解決されます。

  • JavaScriptなのでエディタの補完が効く
  • 関数として書けるので部品化・使い回しがしやすい
  • 何よりWebGPU / WebGL の両対応

「シェーダーをコードとして扱える」感覚に近くて、僕みたいに普段JS/TSを書いている人間にはかなり馴染みやすかったです。

GLSLとTSLを見比べてみる

言葉だけだとピンと来ないと思うので、雰囲気だけ見てみましょう。

たとえば、UV座標を使って横方向に波打つ色を作る、みたいな処理。GLSLだとフラグメントシェーダーにこう書きます(イメージです)。

varying vec2 vUv;
void main() {
  float wave = sin(vUv.x * 10.0) * 0.5 + 0.5;
  gl_FragColor = vec4(wave, vUv.y, 1.0, 1.0);
}

これをTSLで書くと、こんな感じになります。

import { Fn, uv, vec3, vec4, sin } from "three/tsl";
import { MeshBasicNodeMaterial } from "three/webgpu";

const material = new MeshBasicNodeMaterial();
material.colorNode = Fn(() => {
  const st = uv();
  const wave = sin(st.x.mul(10)).mul(0.5).add(0.5);
  return vec4(wave, st.y, 1, 1);
})();

注目してほしいのは、全部JavaScriptで書けているところ。uv()sin() がそのまま関数として呼べて、.mul() .add() のようにメソッドチェーンで計算をつないでいけます。

そして、このコードはWebGPUなら裏でWGSLに、WebGLなら裏でGLSLにコンパイルされます。書き手は出力先を意識しなくていい。ここがTSLの気持ちよさです。

※ TSLはまだ新しく、関数名やインポート先(three/tsl など)はバージョンで変わることがあります。実際に書くときは、three.js公式のサンプル集や、TSL公式リファレンス(Three.js Shading Language / three.js wiki)を基準にするのがおすすめです。

TSLを始めるには

最低限おさえるのはこの3つです。

  1. WebGPURenderer を使うthree/webgpu から読み込む)
  2. MeshBasicNodeMaterial などの「ノードマテリアル」を使う
  3. material.colorNodematerial.positionNode にTSLで書いた処理を渡す

通常の WebGLRendererShaderMaterial の構成とはマテリアル周りが少し変わりますが、Scene・Camera・Meshといった基本構造はThree.jsのままです。Three.jsの基礎を知っていれば、移行のハードルはそこまで高くありません。

(Three.jsそのものが初めての方は、先に [Three.js入門ガイド] を読んでから戻ってくると理解が早いはずです)

いつTSLを使うべき?

僕の今のスタンスはこんな感じです。

  • これから新しく作るなら、TSLで書く(WebGPU時代に向けて素直)
  • 既存のGLSL資産は、無理に全部書き換えない(動いているものはそのまま)

WebGPUが標準になった今、新規の表現はTSLで書いておくと将来の移行コストがかからず、WebGLにもフォールバックできます。一方で、すでにGLSLで書いた作品を急いで置き換える必要はありません。少しずつ慣れていけば十分です。

まとめ

  • TSL = JavaScriptでシェーダーを書き、WGSL/GLSLに自動変換してくれる仕組み
  • WebGPU時代の「シェーダー二重書き問題」を解決してくれる
  • GLSLより補完・部品化がしやすく、JS/TS書きと相性がいい
  • 新規はTSL、既存GLSLは急がず——くらいの温度感でOK

TSLはまだ日本語の情報が少ない領域なので、これから触る人の入口になればうれしいです。僕もXでTSLの作品を出していくので、よかったら覗いてみてください。

次は、TSLの土台になる [GLSL入門] や、[Three.jsでWebGPUを使う(WebGPURenderer移行ガイド)] も読んでみてください。よく使うノードは [TSLノード早見表] にまとめていく予定です。

それでは、よいThree.jsライフを🌊

Three.js
しゅん

しゅん

フロントエンドエンジニア / Webデザイナー。 アメリカ カリフォルニア州生まれ。 音楽、映画、芸術を中心としたサブカルが大好き。 お仕事のご相談は下記リンクのポートフォリオの連絡先からお願いします。

← 記事一覧に戻る