Skip to main content

リアクティブ GPU エンジン設計仕様書

概要

GLRE は、CPU 側の JavaScript コードと GPU 側のシェーダコードを結合するリアクティブエンジンである。 WebGL2 と WebGPU の両方をサポートし、直接 GLSL または WGSL を記述することも、 TypeScript ライクなノードシステムを通じてシェーダを生成することも可能である。

アーキテクチャ構成

CPU-GPU 結合の自動化システム

中核機能は、CPU 側のデータを GPU 側のシェーダプログラムに送信するための設定を自動的に構築することである。 この処理はsrc/index.tsの createGL 関数で管理され、WebGL2 と WebGPU の違いを抽象化する。

createGL 関数は、reev ライブラリの event 関数を使用してリアクティブな GL インスタンスを生成する。 このインスタンスは、uniform、attribute、texture のデータ設定を自動的にキューイングし、タイミングで GPU に転送する。

WebGL2 バックエンド実装

webgl.ts では、OpenGL ES 3.0 ベースのレンダリングパイプラインを実装している。 この実装はクラスではなく関数型アプローチを採用し、クロージャを活用してプライベートな状態を管理する。

WebGL コンテキストから shader program を初期化した後、uniform と attribute の location を nested 関数でキャッシュする。 render 関数、clean 関数、および設定関数(_uniform_attribute_texture)を戻り値として返し、 これらが reev の event 関数によって元の gl オブジェクトにマージされる。

WebGPU バックエンド実装

webgpu.ts では、WebGPU API を使用したレンダリングパイプラインを実装している。 WebGL バックエンドとは異なり、パイプラインの初期化は render 段階で実行される。

これは、attribute や uniform の設定が gl.queue に追加された後、 flush 処理を経てから buffer や bindGroup の layout を構築する必要があるためである。 cached 関数を使用して uniforms、textures、attribs のデータをキャッシュし、 これらの情報を基に createVertexBuffers、createBindGroup、createPipeline の関数で GPU リソースを構築する。

ノードシステム詳細

抽象構文木構築メカニズム

ノードシステムは、JavaScript コードから GLSL/WGSL シェーダコードを生成するための DSL(Domain Specific Language)である。 create.ts の create 関数は、React.createElement と同じ引数形式で抽象構文木を構築する。

NodeProxy オブジェクトは、Proxy パターンを使用して getter/setter による動的な抽象構文木を構築する。 type、props、children のプロパティを持ち、これらの関係性が code 関数によって解析されてシェーダコードに変換される。

抽象構文木の例:
operator(+)
/ \
uniform(a) uniform(b)

コード生成プロセス

code 関数は、抽象構文木を文字列のシェーダコードに変換する中核機能を提供する。 この関数は type による条件分岐を行い、WebGL(GLSL)と WebGPU(WGSL)の両方に対応した文字列を生成する。

生成プロセスは、variables、scopes、headers の三つのカテゴリに分類される。 variables は基本的な演算子のワンライナー生成、scopes は複数行にわたる処理、headers はシェーダ全体の冒頭に追加される定義文である。

NodeContext を通じて、uniform の struct としての統合や、 依存関係のトポロジカルソートなど、全ノードのビルド完了後に必要な後処理を管理する。

型推論システム

infer.ts は、ノードツリーから適切なシェーダ型を推論する機能を実装している。 これは TypeScript の型推論ではなく、JavaScript 実行時に GLSL/WGSL 生成のための型を決定するシステムである。

型推論は、演算子、関数、変数の種類に応じて適切な戻り値型を決定する。 例えば、comparison operators は常に bool を返し、vec 型同士の演算では適切な次元の vec 型を返す。

スコープ管理システム

scope.ts は、複数行のコードを生成するための機能を提供する。 let scope 変数と let define 変数を使用して、現在のスコープコンテキストを管理する。

addToScope 関数によって指定されたスコープに行を追加し、scoped 関数によって特定のスコープを一時的に切り替えて処理を実行する。 If、Loop、Switch などのコードはこのメカニズムでネストされたコードを生成する。

GPU リソース管理

パイプライン構築の自動化

pipeline.ts では、WebGPU 向けのリソース管理機能を提供する createBindings 関数は、 uniform、texture、attribute のリソースに対して自動的に group と binding の番号を割り当てる。

この番号割り当ては、シェーダコード生成時と実際の GPU リソース作成時で一致する必要があるため、 parse.ts の parseUniformHead、parseAttribHead 関数で参照される。

バッファ管理システム

createUniformBuffer、createAttribBuffer の関数は、 JavaScript の number 配列から GPU 用の Float32Array および GPUBuffer を生成する。 uniform バッファは 256 バイト境界に整列され、attribute バッファは頂点データのストライドに基づいてサイズで作成される。

レンダリングパイプライン統合

シェーダコンパイルフロー

webgl.ts および webgpu.ts では、fragment 関数と vertex 関数を呼び出して文字列形式のシェーダコードを生成する。 これらの関数は node/index.ts で定義され、NodeProxy から最終的な GLSL/WGSL コードへの変換を管理する。

生成されたシェーダコードは、WebGL では createProgram 関数、WebGPU では createPipeline 関数によって GPU プログラムとして初期化される。

リアクティブ更新メカニズム

reev ライブラリの durable 関数を使用して、uniform、attribute、texture の設定関数をキューイングする。 これにより、JavaScript コードからの値変更が自動的に GPU に反映される。

update サイクルは、gl.queue.flush()によってトリガーされ、累積された変更を一括して GPU に送信する。 このアプローチにより、レンダリングフレームごとの効率的な更新が実現される。

実装ガイドライン

ノードシステム使用時の注意点

ノードシステムを使用する場合、node.ts のファクトリ関数(uniform、attribute、constant など)から。 NodeProxy を生成し、これらを組み合わせて抽象構文木を構築する。

toVar()メソッドを使用して変数宣言を行い、assign()メソッドを使用して値の代入を実行する。 Fn()関数を使用してカスタム関数を定義し、setLayout()メソッドで引数と戻り値の型を明示的に指定する。

直接シェーダコード使用時の指針

ノードシステムを使用せず、直接 GLSL または WGSL を記述する場合は、createGL の vs および fs プロパティに文字列として渡す。 この場合でも、uniform、attribute、texture の設定は GL インスタンスのメソッドを通じて行う。

シェーダコード内で使用する uniform 名、attribute 名は、JavaScript 側の設定と一致させる必要がある。 WebGPU の場合は、group と binding の番号も適切に設定する。

エラー回避のための設計原則

NodeProxy の children 配列の設計パターンを理解することが重要である。 例えば、If ノードでは condition と scope が交互に配置され、最後の要素が Else の場合は条件なしで配置される。

struct 定義時は、依存関係のトポロジカルソートが実行されるため、循環参照を避ける設計が必要である。 uniform の group/binding 番号は自動割り当てされるため、手動での指定は推奨されない。

TypeScript コーディングスタイルガイド

基本設計思想

関数型プログラミング実装

class キーワードを使用せず、クロージャベースのコンストラクターパターンを採用する。 プライベート変数のアクセス制御と状態管理を実現する。

コンストラクター関数の最初で初期化処理を完了し、プライベート変数とメソッドを定義した後、 パブリック API として必要な要素のみをオブジェクトで返す。 カプセル化の原則を保ちつつ、JavaScript の特性を活用する。

TypeScript 型安全性の適用

TypeScript は型ヒントとして使用し、複雑な型定義によってコードが複雑化することを避ける 型推論の恩恵を得つつ、JavaScript がメインである状況を維持して、実装の柔軟性と開発効率を両立する

複雑な型が必要な場合は一旦 as キーワードを活用して型の橋渡しを行う。 型安全性よりも実装の簡潔性を重視して、開発者の認知負荷を軽減し、問題解決に集中する。

コード構造とファイル設計

ファイル分割の原則

各ファイルは 100 行前後を目標とし、この制限により責任範囲を明確化する。 ファイル名は 1 単語で決定し、複数単語が必要な場合はディレクトリ構造を見直す。

基本のファイル構成として、types.ts、const.ts、config.ts、index.ts のパターンを採用する。 この構成により、各ファイルの役割が自明となり、開発者間での認識を統一する。

命名規則と一貫性

変数と関数の命名パターン

小文字から始まる識別子には camelCase を使用し、boolean 変数は has 前置詞は使用せず、is 前置詞で始める。 関数名は動詞から始めて、その機能を示す。

大文字から始まる識別子には PascalCase を使用し、型とインターフェースの定義に適用する。 interface の使用を優先し、extends の互換性を重視する。 type キーワードは、typeof 演算子やユニオン型など、interface で定義できない場合のみ使用する。

ファイル名とディレクトリ構造

ファイル名に camelCase を使用せず、シンプルな単語で構成する パッケージのサブディレクトリは、import パスとして使用される際の利便性を考慮して決定する

書式設定の仕様

インデント設定による構造の強制

8 文字スペースインデントにより、コード構造の可視化を強化する。 この設定により、3 レベル以上のインデントは読みづらくなり、関数分割やリファクタリングを促進する。

120 文字の行幅制限により長さを確保し、セミコロン無しの設定でコードの簡潔性を実現する。 single quote の使用により、文字列表記を統一する。

条件分岐の記述

複雑な条件は事前に boolean 変数として定義し、条件の意図を明確にする。 const isValid = condition1 && condition2の形で条件をまとめ、 if 文ではif (isValid) returnの形で早期リターンを活用する。

実装パターンの統一

クロージャベースコンストラクターパターン

コンストラクター関数としてconst createInstance = (args) => {}の形を採用し、関数の最初で初期化処理を完了する。 プライベート変数はletconstで定義し、パブリック API は最後にオブジェクトとして返す。

good: const createRenderer = (config) => { const context = initContext(config); const render = () => context.draw(); return { render } }

分岐処理の統一パターン

switch キーワードを使用せず、if-return パターンで分岐処理を実装する。 このパターンにより、条件の複雑化を防ぎ、各分岐の独立性を保つ。

good: const getFormat = (count) => { if (count === 2) return 'vec2'; if (count === 3) return 'vec3'; return 'float' }

対称性の重視

関連する関数やモジュール間で構造の対称性を保つ。 入力と出力、初期化と破棄、設定と取得など、対となる操作では一貫したパターンを適用して、 システム全体の理解しやすさを向上させる。

型定義と制約

型安全性の実現

interface の定義を優先し、オブジェクトの構造を明確にする。 union type による列挙表現を活用し、enum キーワードの使用を避ける。

関数定義の統一

function 宣言ではなく、const のアロー関数を使用する。 この統一により、関数の性質を明確にし、ホイスティングによる意図しない動作を防ぐ。

エラーハンドリングとロギングの禁止

シンプルな実装の維持

try-catch 構文や console.log の使用を避け、コードの簡潔性を保つ。 エラー処理が必要な場合は、関数の戻り値や Promise の reject を活用し、呼び出し側での処理を促す。

実装の複雑化を避けるため、型安全性のための過度なチェックは行わず、実行時の柔軟性を重視する。

import と export の構造

モジュール管理の最適化

import文の配置は、外部ライブラリ、プロジェクト内のヘルパー、ユーティリティ、型定義の順序で行う。

type import は最後にまとめ、値の import と明確に分離する。 default export の使用は最小限に留め、named export による明示的な API 設計を重視する。

関数内の構造化

行間の管理

関数内では行間の挿入を最小限に抑え、処理の密度を高める。 const 宣言は詰めて配置し、let への移行時に行間を開けて、変数の役割変化を視覚的に表現する。

関数間では明確な行間を設け、各関数の独立性を強調する。 この管理により、100 行制限内でのコード配置を可能にする。

ノードシステム言語仕様書

基本概念

ノードシステムは、JavaScript から GLSL/WGSL シェーダコードを生成するドメイン固有言語である。 このシステムは抽象構文木を構築し、それを目的のシェーダ言語に変換する仕組みを提供する。

JavaScript DSL        抽象構文木          シェーダコード
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│vec4(1,0,0,1)│ ───→ │ NodeProxy │───→│vec4(1,0,0,1)│
│.mul(2.0) │ │ children[] │ │* 2.0 │
│.add(pos) │ │ type/props │ │+ position │
└─────────────┘ └─────────────┘ └─────────────┘

ノード構築システム

NodeProxy アーキテクチャ

NodeProxy オブジェクトは、Proxy パターンを使用してメソッドチェーンと動的プロパティアクセスを実現する。 各 NodeProxy は type、props、children の構造を持ち、これらが組み合わさって抽象構文木を形成する。

NodeProxy 構造:
┌─────────────────┐
│ NodeProxy │
├─────────────────┤
│ type: string │ ── ノード種別
│ props: object │ ── プロパティ
│ children: [] │ ── 子ノード配列
│ listeners: Set │ ── イベントリスナー
└─────────────────┘

getter では、プロパティ名に基づいて演算子、関数、変換、スウィズリングの処理を判定し、NodeProxy を返す。 setter では、listener パターンを使用して値の更新を管理する。

抽象構文木の構造

抽象構文木は二分木構造だが、children プロパティを使用して可変長の子ノードをサポートする。 これにより、関数呼び出しの引数や、If 文の条件分岐を表現できる。

関数呼び出しの例:
function_node
/ | \
func_name arg1 arg2

型システムと変換

基本型定義

型システムは、float、int、bool、vec2、vec3、vec4、mat2、mat3、mat4 のシェーダ型を提供する。 各型はファクトリ関数を通じて生成され、型推論により型に変換される。

型名ファクトリ関数説明GLSL/WGSL 対応
floatfloat(value)32 ビット浮動小数点float / f32
intint(value)32 ビット整数int / i32
boolbool(value)論理値bool / bool
vec2vec2(x, y)2 次元ベクトルvec2 / vec2<f32>
vec3vec3(x, y, z)3 次元ベクトルvec3 / vec3<f32>
vec4vec4(x, y, z, w)4 次元ベクトルvec4 / vec4<f32>
mat2mat2(...)2x2 行列mat2 / mat2x2<f32>
mat3mat3(...)3x3 行列mat3 / mat3x3<f32>
mat4mat4(...)4x4 行列mat4 / mat4x4<f32>

型変換メソッド

メソッド名戻り値型説明
.toFloat()float浮動小数点型に変換
.toInt()int整数型に変換
.toBool()bool論理型に変換
.toVec2()vec22 次元ベクトルに変換
.toVec3()vec33 次元ベクトルに変換
.toVec4()vec44 次元ベクトルに変換
.toColor()vec3カラー型に変換
.toMat2()mat22x2 行列に変換
.toMat3()mat33x3 行列に変換
.toMat4()mat44x4 行列に変換

型変換は明示的な変換関数(toFloat()、toVec3()など)と型昇格をサポートする。 float と vec3 の演算では、float が vec3 にブロードキャストされる。

型推論メカニズム

型推論エンジンは実行時にノードツリーを解析し、各ノードの戻り値型を決定する。 演算子の型推論では、左右のオペランドの型優先順位を比較し、高い優先度の型を結果型として選択する。

比較演算子は bool 型を返す。 論理演算子は bool 型を返す。 ベクトル型同士の演算では、高い次元のベクトル型が優先される。

演算子システム

数学演算子

演算子メソッド記号説明戻り値型
.add(x)+加算高優先度型
.sub(x)-減算高優先度型
.mul(x)*乗算高優先度型
.div(x)/除算高優先度型
.mod(x)%剰余高優先度型

比較演算子

演算子メソッド記号説明戻り値型
.equal(x)==等価比較bool
.notEqual(x)!=不等価比較bool
.lessThan(x)<小なり比較bool
.greaterThan(x)>大なり比較bool
.lessThanEqual(x)<=以下比較bool
.greaterThanEqual(x)>=以上比較bool

論理演算子

演算子メソッド記号説明戻り値型
.and(x)&&論理積bool
.or(x)||論理和bool
.not()!論理否定bool
.xor(x)^^排他的論理和bool

ビット演算子

演算子メソッド記号説明戻り値型
.bitAnd(x)&ビット積入力型
.bitOr(x)|ビット和入力型
.bitXor(x)^ビット排他和入力型
.bitNot()~ビット否定入力型
.shiftLeft(x)<<左シフト入力型
.shiftRight(x)>>右シフト入力型

代入演算子

| 演算子メソッド | 記号 | 説明 | 戻り値型 | | ---------------------- | ----- | ---------------- | ------------ | ------ | | .addAssign(x) | += | 加算代入 | 入力型 | | .subAssign(x) | -= | 減算代入 | 入力型 | | .mulAssign(x) | *= | 乗算代入 | 入力型 | | .divAssign(x) | /= | 除算代入 | 入力型 | | .modAssign(x) | %= | 剰余代入 | 入力型 | | .bitAndAssign(x) | &= | ビット積代入 | 入力型 | | .bitOrAssign(x) | | = | ビット和代入 | 入力型 | | .bitXorAssign(x) | ^= | ビット排他和代入 | 入力型 | | .shiftLeftAssign(x) | <<= | 左シフト代入 | 入力型 | | .shiftRightAssign(x) | >>= | 右シフト代入 | 入力型 |

数学関数ライブラリ

三角関数

関数名説明引数型戻り値型
sin(x)正弦スカラー/ベクトル入力型
cos(x)余弦スカラー/ベクトル入力型
tan(x)正接スカラー/ベクトル入力型
asin(x)逆正弦スカラー/ベクトル入力型
acos(x)逆余弦スカラー/ベクトル入力型
atan(x)逆正接スカラー/ベクトル入力型
atan2(y, x)2 引数逆正接スカラー/ベクトル高優先度型

指数・対数関数

関数名説明引数型戻り値型
pow(x, y)べき乗スカラー/ベクトル高優先度型
pow2(x)2 乗スカラー/ベクトル入力型
pow3(x)3 乗スカラー/ベクトル入力型
pow4(x)4 乗スカラー/ベクトル入力型
sqrt(x)平方根スカラー/ベクトル入力型
inverseSqrt(x)逆平方根スカラー/ベクトル入力型
exp(x)自然指数スカラー/ベクトル入力型
exp2(x)2 の指数スカラー/ベクトル入力型
log(x)自然対数スカラー/ベクトル入力型
log2(x)2 底対数スカラー/ベクトル入力型

一般数学関数

関数名説明引数型戻り値型
abs(x)絶対値スカラー/ベクトル入力型
sign(x)符号スカラー/ベクトル入力型
floor(x)床関数スカラー/ベクトル入力型
ceil(x)天井関数スカラー/ベクトル入力型
round(x)四捨五入スカラー/ベクトル入力型
fract(x)小数部スカラー/ベクトル入力型
trunc(x)整数部スカラー/ベクトル入力型
min(x, y)最小値スカラー/ベクトル高優先度型
max(x, y)最大値スカラー/ベクトル高優先度型
clamp(x, min, max)範囲制限スカラー/ベクトル高優先度型
saturate(x)0-1 制限スカラー/ベクトル入力型
mix(x, y, a)線形補間スカラー/ベクトル高優先度型
step(edge, x)ステップ関数スカラー/ベクトル高優先度型
smoothstep(edge0, edge1, x)スムーズステップスカラー/ベクトル高優先度型

ベクトル関数

関数名説明引数型戻り値型
length(x)ベクトル長ベクトルfloat
distance(x, y)距離ベクトルfloat
dot(x, y)内積ベクトルfloat
cross(x, y)外積vec3vec3
normalize(x)正規化ベクトル入力型
reflect(I, N)反射ベクトル入力型
refract(I, N, eta)屈折ベクトル入力型

微分関数

関数名説明引数型戻り値型
dFdx(x)X 方向偏微分スカラー/ベクトル入力型
dFdy(x)Y 方向偏微分スカラー/ベクトル入力型
fwidth(x)微分幅スカラー/ベクトル入力型

ユーティリティ関数

関数名説明引数型戻り値型
oneMinus(x)1 から減算スカラー/ベクトル入力型
negate(x)符号反転スカラー/ベクトル入力型
reciprocal(x)逆数スカラー/ベクトル入力型

スウィズリング操作

ベクトル成分アクセス

ベクトル型の NodeProxy では、.xyz、.rgb、.stpq などのスウィズリング操作が認識される。 これらの操作は、member ノードとして表現され、次元数の戻り値型を持つ。

パターン説明使用例
xyzw位置座標vec.xyz, vec.xy
rgba色成分color.rgb, color.rg
stpqテクスチャ座標uv.st, uv.s
スウィズリング例:
vec4(1,2,3,4) ─┬─ .xyz ──→ vec3(1,2,3)
├─ .xy ──→ vec2(1,2)
├─ .w ──→ float(4)
└─ .rgba ──→ vec4(1,2,3,4)

変数とスコープ管理

変数宣言システム

toVar()メソッドは、式ノードを変数宣言ノードに変換する。 この処理では、変数 ID を生成し、declare type のノードを通じてスコープに変数宣言文を追加する。

ファクトリ関数群

関数名用途生成ノード型説明
attribute(value, id)頂点属性attribute頂点データ受信
uniform(value, id)ユニフォームuniformCPU-GPU データ転送
constant(value, id)定数constantコンパイル時定数
variable(id)変数variableローカル変数
builtin(id)ビルトインbuiltinシェーダビルトイン変数
varying(node, id)バリングvarying頂点-フラグメント間データ

スコープ操作

メソッド名説明戻り値
.toVar(name)変数化変数ノード
.assign(value)代入代入文ノード

スコープ階層構造

スコープシステムは、scope 変数と define 変数を使用して、コンテキストを管理する。 scoped()関数によりスコープを切り替え、スコープ内での処理を実行する。

スコープ階層:
Global Scope
├── Function Scope
│ ├── If Scope
│ ├── Loop Scope
│ └── Switch Scope
└── Struct Scope

addToScope()関数は、現在のスコープにノードを追加する機能である。 return 文の場合は、define 変数の inferFrom プロパティにも追加され、関数の戻り値型推論に使用される。

制御構造

条件分岐

If()関数は、条件式とコールバック関数を受け取り、if 文のノード構造を構築する ElseIf()と Else()メソッドをチェーンして、条件分岐を表現できる

制御構造構文説明
If(condition, callback)if 文条件分岐開始
.ElseIf(condition, callback)else if 文追加条件
.Else(callback)else 文デフォルト処理

ループ構造

ループ種別構文説明
Loop(count, callback)for 文回数指定ループ
Loop(condition, callback)while 文条件ループ
Break()break 文ループ脱出
Continue()continue 文ループ継続

Loop()関数は、反復回数と反復処理を定義する。 反復処理内では、生成されるループ変数 i にアクセスでき、これを使用して配列アクセスや計算処理を記述できる。

Switch 文

制御構造構文説明
Switch(value)switch 文多分岐開始
.Case(value, callback)case 文値による分岐
.Default(callback)default 文デフォルト処理

条件演算子

select()関数は、三項演算子の機能を提供する。 条件式、真の場合の値、偽の場合の値を受け取り、条件分岐ノードを生成する。

children 配列では、条件式とスコープが交互に配置され、Else 節では条件式なしでスコープのみが配置される。 この配置により、コード生成時に条件分岐構造を判定する。

select(条件がfalseのときの値, 条件がtrueのときの値, 条件の boolean)
// or
(条件がfalseのときの値).select(条件がtrueのときの値, 条件の boolean)

関数定義システム

Fn()関数の詳細

Fn()関数は、シェーダ関数を定義するための仕組みを提供する。 コールバック関数内で定義された処理は、スコープを持つ関数ノードとして構築される。

関数定義の構造:
define_node
/ \
scope layout_info
/ | \
name inputs return_type

レイアウト仕様

プロパティ説明
namestring関数名
typeConstants戻り値型
inputsArray引数仕様配列

パラメータ処理

関数のパラメータは、layout が指定されている場合はそれに従い、指定されていない場合は実引数から型推論される。 各パラメータは variable ノードとして生成され、関数スコープ内でアクセス可能になる。

setLayout()メソッドを使用して、関数の名前、戻り値型、引数リストを指定できる。 これにより、型安全性と可読性を向上させられる。

構造体システム

構造体定義

struct()関数は、フィールド定義とインスタンス生成の二段階のファクトリを提供する。 フィールド定義では、各フィールドの名前と型を指定し、インスタンス生成では初期値を設定できる。

構造体定義フロー:
struct(fields) ──→ ファクトリ ──→ (initialValues) ──→ インスタンス
↓ ↓
フィールド仕様 初期化済み構造体

構造体定義は、dependencies システムを通じてトポロジカルソートされ、依存関係の順序でヘッダーコードが生成される。

メンバーアクセス

構造体のメンバーアクセスは、member ノードを通じて表現される。 フィールド名が構造体定義の fields プロパティに存在する場合、そのフィールドの型が推論される。

ユニフォームとアトリビュート

ユニフォーム変数

uniform()関数は、CPU から GPU にデータを転送するためのユニフォーム変数を定義する。 生成された NodeProxy には、値の変更を監視する listener が設定され、リアクティブな更新が可能になる。

ユニフォーム型JavaScript 型GLSL 型WGSL 型
スカラーnumberfloatf32
ベクトルnumber[]vec2/3/4vec2/3/4<f32>
行列number[]mat2/3/4mat2x2/3x3/4x4<f32>
テクスチャstringsampler2Dtexture_2d<f32>

ユニフォーム変数の型は、初期値から推論されるか、型変換ノードを通じて指定される テクスチャ型の場合は、処理パスが実行される

アトリビュート変数

attribute()関数は、頂点データを受け取るためのアトリビュート変数を定義する。 配列長と頂点数からストライドが計算され、型推論が行われる。

アトリビュート型ストライドGLSL 型WGSL 型
1 成分1floatf32
2 成分2vec2vec2<f32>
3 成分3vec3vec3<f32>
4 成分4vec4vec4<f32>

ビルトイン変数

builtin()関数は、position、normal などのビルトイン変数にアクセスするためのノードを生成する。 これらの変数は、レンダリングパイプラインの各段階で提供される値である。

ビルトイン変数説明利用可能段階
position頂点位置vec4頂点・フラグメント
normal法線ベクトルvec3フラグメント
uvテクスチャ座標vec2フラグメント
color頂点カラーvec4フラグメント

テクスチャサンプリング

テクスチャ関数

texture()関数は、テクスチャサンプリング操作を表現する function ノードを生成する。 引数の数に応じて、サンプリングかミップマップレベル指定サンプリングかが判定される。

関数構文説明戻り値型
texture(sampler, uv)基本サンプリングvec4
texture(sampler, uv, level)ミップマップレベル指定vec4

テクスチャ名は、uniform システムと連携してバインディング番号が割り当てされ、シェーダコード生成時にサンプラー参照が生成される。

コード生成規則

ヘッダー管理

uniformHead、structHead、defineHead などのヘッダー情報は、NodeContext を通じて管理される。 これらは全ノードの処理完了後に、依存関係順序でソートされてシェーダコードの冒頭に配置される。

ヘッダー生成順序:
Dependencies ──→ TopologicalSort ──→ Header Order
↓ ↓ ↓
構造体関係 トポロジカルソート 依存順序
関数関係 アルゴリズム ヘッダー

バリング処理

WebGPU のバリング(頂点シェーダから フラグメントシェーダへのデータ受け渡し)は、varying()関数を通じて管理される。 この関数は、location 番号を割り当て、両シェーダに対応するバリング宣言を生成する。

依存関係解決

構造体定義や関数定義では、相互参照や循環参照を処理するため、トポロジカルソートアルゴリズムが使用される。 visiting セットを使用して循環参照を検出し、順序でヘッダーコードを生成する。

依存関係解決:
Node Graph ──→ Dependency Analysis ──→ Sorted Headers
↓ ↓ ↓
ノード関係 依存関係分析 ソート済みヘッダー
循環検出 visiting セット コード生成順序