Skip to content

svey-xyz/simple-shader-component

Repository files navigation

Simple Shader Component

by svey

GitHub release (latest by date including pre-releases) GitHub commits GNU license v3.0 Bundle size

Description

This library provides a simple to use webgl shader component, with included framework wrappers and strong typing. Shaders are powerful tools and can be used to add a lot of visual interest to your web project. However, setting-up many shader tools can be complicated and add a large bundle to your project, this library provides a simple core package to make rendering a shader in your DOM incredibly easy.

Core Concepts

Why

While libraries like three.js are amazing, not every project requires all the provided features. That's where simple-shader-component comes in; this is a zero-dependency library that provides a simple to use component for rendering GLSL shaders on the web.

Installation & Usage

bun i simple-shader-component

The base class and types are all exported from the root of the package. Framework wrappers are available under sub exports.

import { SimpleShaderCanvas } from 'simple-shader-component/react'

Note: Right now only the React wrapper is included. If there's interest, or if my workflow requires it, I will add additional wrappers.

Hooks

Hooks can be added to any of the class methods, to add a hook you can pass it on construction or using the exposed add hook method.

import { Shader, MethodName } from 'simple-shader-component' // import types from base package

const hook = {
	methodName: MethodName.RENDER,
	hook: (shader: Shader) => void
}

Shader.addHook(hook) // use addHook method
<SimpleShaderCanvas args={{ hooks:[hook] }} /> // or pass on construction

Basic Usage

'use client' directive is required to set hooks. If you're not using hooks it can be done in a server component.

'use client'

import { SimpleShaderCanvas } from 'simple-shader-component/react'
import { Shader, UniformValue } from 'simple-shader-component'

// Define shaders as strings, or import from a glsl file with a loader
import { frag, vert } from '.your-custom-shaders'

// Example uniform to track elapsed time in the shader
const uniforms: Array<UniformValue> = [
	{
		name: 'u_time',
		type: "float",
		value: 0.0
	}
]

export const Test = () => {
	// Simple hook to update a uniform
	const loopLogic = (shader: Shader) => {
		const uTime: UniformValue = {
			name: 'u_time',
			type: 'float',
			value: shader.getElapsedTime() // Uses exposed method of shader
		}
		shader.setUniform(uTime)
	}

	// Define which method to attach the hook to
	const loopHook = {
		methodName: MethodName.LOOP,
		hook: loopLogic
	}

	// Render component with args
	return <SimpleShaderCanvas args={{ uniforms: uniforms, fragShader: frag, vertShader: vert, hooks: [loopHook] }} />
}

Coming Soon

  • improved documentation
  • screenshots & examples of how shaders as a component can be used to add visual interest
  • roadmap