Skip to main content

🌇 glre

 npm version  downloads  license MIT  docs available  bundle size

glre is a simple glsl and wgsl Reactive Engine on the web and native via TypeScript, React, Solid and more.

test1test2test3raymarch1raymarch2raymarch3raymarch4raymarch5raymarch6

Installation

npm install glre

Documentation

Docs : glre Introduction
API : glre API and feature
Guide : Creating a scene

Ecosystem

⛪️ reev: reactive event state manager
🔮 refr: request animation frame

Staying informed

github discussions welcome✨
@tseijp twitter
tsei.jp articles

What does it look like?

glre simplifies WebGl2 / WebGPU programming via TypeScript, React, Solid and more (live demo).

4
import { createRoot } from 'react-dom/client'
import { useGL, vec4, fract, position, iResolution } from 'glre/react'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)

const App = () => {
const gl = useGL({ frag })
return <canvas ref={gl.ref} />
}

createRoot(document.getElementById('root')).render(<App />)

react-native supported (codesandbox demo)

import { GLView } from 'expo-gl'
import { registerRootComponent } from 'expo'
import { useGL, vec4, fract, position, iResolution } from 'glre/native'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)

const App = () => {
const gl = useGL({ frag })
return <GLView style={{ flex: 1 }} onContextCreate={gl.ref} />
}

registerRootComponent(App)

solid js supported (codesandbox demo)

import { render } from 'solid-js/web'
import { onGL, vec4, fract, position, iResolution } from 'glre/solid'
const frag = c4(fract(position.xy.div(iResolution)), 0, 1)

const App = () => {
const gl = onGL({ frag })
return <canvas ref={gl.ref} />
}

render(() => <App />, document.getElementById('root'))

esm supported (codesandbox demo)

<script type="module">
import createGL from 'https://esm.sh/glre'
import { vec4, fract, position, iResolution } from 'https://esm.sh/glre'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)
function App() {
const el = document.createElement('canvas')
createGL({ el, frag }).mount()
document.body.append(el)
}
document.addEventListener('DOMContentLoaded', App)
</script>

Node System

glre now features a powerful node-based shader system inspired by Three.js Shading Language (TSL). This system allows you to write shaders using TypeScript-like syntax and automatically handles the conversion to both WebGL2 and WebGPU shaders.

The node system provides a declarative approach to shader creation, making your code more readable, maintainable, and portable across different rendering backends.

Node Types and Functions

The node system provides various types and functions that mirror GLSL functionality:

// Basic types
import { float, int, vec2, vec3, vec4, mat3, mat4 } from 'glre'

// Built-in variables
import { position, position, iResolution, iTime } from 'glre'

// Math functions
import { sin, cos, abs, pow, mix, clamp, normalize } from 'glre'

// Texture functions
import { texture, textureCube, sampler2D } from 'glre'

Creating Custom Functions

You can define reusable shader functions using the Fn constructor:

import { Fn, vec3, sin, cos, float } from 'glre'

// Define a function that creates a rotation matrix
const rotateY = Fn(([angle = float(0)]) => {
const s = sin(angle)
const c = cos(angle)
return mat3(c, 0, s, 0, 1, 0, -s, 0, c)
})

// Use the function in your shader
const rotatedPosition = rotateY(iTime).mul(position)

Conditional Logic

The node system supports conditional operations:

import { If, vec4, lessThan } from 'glre'

// Create a conditional color output
const color = vec4(1, 0, 0, 1).toVar()

If(position.y.lessThan(0.5), () => {
color.assign(vec4(0, 1, 0, 1))
})

// Use the color in your shader
const fragment = color

Uniforms

The node system provides a powerful way to define and manage uniform values in your shaders:

import { createRoot } from 'react-dom/client'
import { useGL } from 'glre/react'
import { uniform, vec3, vec4 } from 'glre'

const uRand = uniform(1.0)

// Create a simple pulsing color shader
const App = () => {
const gl = useGL({
fragment: vec4(vec3(uRand), 1.0),
loop() {
pulse.set(0.5 + 0.5 * Math.random())
},
})
return <canvas ref={gl.ref} />
}

createRoot(document.getElementById('root')).render(<App />)

Attributes

Attributes allow you to define per-vertex data for your shaders:

import { createRoot } from 'react-dom/client'
import { useGL } from 'glre/react'
import { attribute, vec3, vec4 } from 'glre'

// Define vertex positions
const positions = attribute(-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0)

// Create a shader that uses attributes
const App = () => {
const gl = useGL({ vertex: positions })
return <canvas ref={gl.ref} />
}

createRoot(document.getElementById('root')).render(<App />)

WebGL2 and WebGPU Support

The node system is designed to work with both WebGL2 and WebGPU, providing a seamless transition path as browsers adopt the new standard. Your shader code written with the node system will automatically compile to the appropriate shading language (GLSL ES 3.0 for WebGL2, WGSL for WebGPU) based on the available renderer.

PRs

welcome✨

LICENSE

MIT⚾️