API リファレンス
WebGL/WebGPU を統一する軽量グラフィックスライブラリ。 glre は WebGL2 と WebGPU の複雑な API を統一し、 TypeScript の型安全性とリアクティブプログラミングの利点を活かしたモダンなグラフィックスライブラリです。
初期化
フレームワーク統合
- React
- Solid.js
- React Native
- Vanilla JS
import { useGL } from 'glre/react'
const Component = () => {
const gl = useGL({
frag: fragmentShader,
width: 800,
height: 600,
})
return <canvas ref={gl.ref} />
}
import { onGL } from 'glre/solid'
const Component = () => {
const gl = onGL({
frag: fragmentShader,
width: 800,
height: 600,
})
return <canvas ref={gl.ref} />
}
import { GLView } from 'expo-gl'
import { useGL } from 'glre/native'
const Component = () => {
const gl = useGL({
frag: fragmentShader,
})
return <GLView style={{ flex: 1 }} onContextCreate={gl.ref} />
}
import { createGL } from 'glre'
const gl = createGL({
el: document.querySelector('canvas'),
frag: fragmentShader,
})
gl.mount()
設定オプション
GL 設定
基本的な WebGL/WebGPU 設定を制御します。
プロパティ | 型 | デフォルト | 説明 |
---|---|---|---|
el | HTMLCanvasElement | - | キャンバス要素 |
width | number | window.innerWidth | キャンバス幅 |
height | number | window.innerHeight | キャンバス高さ |
isWebGL | boolean | 自動判定 | WebGL 強制使用 |
isLoop | boolean | true | アニメーションループ |
count | number | 6 | 頂点数 |
シェーダー設定
const gl = useGL({
// フラグメントシェーダー(Node System または文字列)
frag: fragmentShader,
fs: fragmentShader, // 別名
// 頂点シェーダー(オプショナル)
vert: vertexShader,
vs: vertexShader, // 別名
})
データ管理
Uniform 変数
シェーダーへの定数値を設定します。
- 単一値
- オブジェクト
- リアクティブ
// 数値
gl.uniform('iTime', performance.now() / 1000)
// ベクトル
gl.uniform('iResolution', [width, height])
gl.uniform('iMouse', [mouseX, mouseY])
gl.uniform({
iTime: performance.now() / 1000,
iResolution: [width, height],
iMouse: [mouseX, mouseY],
uColor: [1.0, 0.0, 0.0],
})
// フレーム毎に自動更新
gl.uniform('iTime', () => performance.now() / 1000)
// マウス位置の自動追従
gl.uniform('iMouse', () => [gl.mouse[0], gl.mouse[1]])
Attribute 変数
頂点データを設定します。
// 頂点位置
gl.attribute('a_position', [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])
// 複数属性の一括設定
gl.attribute({
a_position: positions,
a_texCoord: uvCoordinates,
a_normal: normals,
})
テクスチャ
画像リソースをシェーダーで使用します。
- 画像ファイル
- Canvas
- 複数テクスチャ
gl.texture('diffuse', '/path/to/texture.jpg')
gl.texture('normal', '/path/to/normal.png')
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// canvas に描画...
gl.texture('dynamicTexture', canvas)
gl.texture({
diffuse: '/textures/diffuse.jpg',
normal: '/textures/normal.jpg',
roughness: '/textures/roughness.jpg',
})
イベントシステム
ライフサイクル
const gl = useGL({
// 初期化時(一度だけ実行)
init() {
console.log('GL コンテキスト初期化完了')
},
// マウント時
mount() {
console.log('レンダリング開始')
},
// クリーンアップ時
clean() {
console.log('リソース解放')
},
})
フレームコールバック
- アニメーションループ
- キューイング
const gl = useGL({
loop(deltaTime) {
// フレーム毎の処理
gl.uniform('iTime', performance.now() / 1000)
gl.uniform('iFrame', gl.frame.count)
},
})
// 一回だけ実行
gl.queue(() => {
gl.uniform('oneTimeValue', computeValue())
})
// 継続実行(true を返す限り継続)
gl.queue((deltaTime) => {
if (shouldContinue) {
updateAnimation(deltaTime)
return true
}
return false
})
インタラクション
const gl = useGL({
// マウス移動
mousemove(event) {
const x = event.clientX / gl.size[0]
const y = 1.0 - event.clientY / gl.size[1]
gl.uniform('iMouse', [x, y])
},
// リサイズ
resize(width, height) {
gl.uniform('iResolution', [width, height])
},
// カスタムレンダリング
render() {
// 独自の描画処理
customRenderLogic()
},
})
Node System 統合
基本的な使用
import { vec2, vec3, vec4, sin, cos, fract } from 'glre/node'
const fragmentShader = Fn(() => {
const uv = position.xy.div(iResolution).toVar()
const time = iTime.toVar()
const color = vec3(sin(time.add(uv.x.mul(10))), cos(time.add(uv.y.mul(10))), sin(time.mul(2)))
.mul(0.5)
.add(0.5)
return vec4(color, 1.0)
})
const gl = useGL({ frag: fragmentShader })
関数とスコープ
const noiseFunction = Fn((args) => {
const [uv, time] = args
return sin(uv.x.mul(10).add(time))
.mul(sin(uv.y.mul(10).add(time)))
.mul(0.5)
.add(0.5)
})
const mainShader = Fn(() => {
const uv = position.xy.div(iResolution).toVar()
const noise = noiseFunction(uv, iTime)
return vec4(noise, noise, noise, 1.0)
})