Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fragment-shader

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fragment-shader - npm Package Compare versions

Comparing version 0.1.3 to 0.1.5

types/shader.ts

111

classes/Editor.ts

@@ -1,2 +0,2 @@

import Shader, { type UniformValue } from './Shader';
import Shader from './Shader';
import { EditorView, basicSetup } from 'codemirror';

@@ -13,18 +13,6 @@ import { EditorViewConfig, ViewUpdate, keymap } from '@codemirror/view';

import { DEFAULT_FRAGMENT_SHADER, DEFAULT_UNIFORMS } from '../constants/shader';
import { type UniformValue } from '../types/shader';
import { type EditorConfig } from '../types/editor';
import '../css/editor.css';
export interface EditorConfig {
target?: HTMLElement;
shader?: string;
uniforms?: UniformValue[];
debug?: boolean;
onError?: Function;
onSuccess?: Function;
onUpdate?: Function;
width?: number;
height?: number;
dpr?: number;
fillViewport?: boolean;
}
const buildAtoms = (uniforms: UniformValue[]) => ({

@@ -41,3 +29,3 @@ ...uniforms.reduce((acc: any, uniform: any) => {

const defineLanguageDetails = (uniforms: any) =>
const defineLanguageDetails = (uniforms: UniformValue[]) =>
clike({

@@ -56,3 +44,3 @@ name: 'FragmentShader',

uniforms: DEFAULT_UNIFORMS,
debug: true,
showErrors: true,
onError: () => {},

@@ -65,2 +53,3 @@ onSuccess: () => {},

fillViewport: true,
showLineNumbers: true,
};

@@ -123,7 +112,18 @@

constructor(config: EditorConfig = DEFAULT_CONFIG) {
this.config = {
...DEFAULT_CONFIG,
...config,
};
constructor(
configOrShader: EditorConfig | string = DEFAULT_CONFIG,
config: EditorConfig = DEFAULT_CONFIG
) {
if (typeof configOrShader === 'string') {
this.config = {
...DEFAULT_CONFIG,
...config,
shader: configOrShader,
};
} else {
this.config = {
...DEFAULT_CONFIG,
...configOrShader,
};
}

@@ -144,2 +144,4 @@ if (

this.container.classList.add('editor');
if (!this.config.showLineNumbers)
this.container.classList.add('no-line-numbers');

@@ -154,3 +156,3 @@ this.sizeContainer();

uniforms,
debug: this.config.debug,
debug: this.config.showErrors,
onError: this.onError.bind(this),

@@ -161,3 +163,3 @@ onSuccess: this.onSuccess.bind(this),

dpr: this.config.dpr,
fillViewport: this.config.fillViewport,
fillViewport: false,
});

@@ -181,6 +183,6 @@

? window.innerWidth
: this.config.width;
: this.config.width || window.innerWidth;
const height = this.config.fillViewport
? window.innerHeight
: this.config.height;
: this.config.height || window.innerHeight;
this.container.style.position = 'relative';

@@ -190,2 +192,8 @@ this.container.style.width = width + 'px';

this.container.style.overflow = 'hidden';
if (!this.shader) return;
this.shader.size = {
width,
height,
dpr: window.devicePixelRatio,
};
}

@@ -204,22 +212,47 @@

onPaste({ clipboardData }: ClipboardEvent) {
if (clipboardData === null) return;
const string = clipboardData.getData('text');
const string = clipboardData?.getData?.('text') || '';
const isShaderToy = string.indexOf('mainImage') !== -1;
if (isShaderToy) {
this.config.shader = formatShadertoySource(string);
if (clipboardData === null || !isShaderToy) return;
this.shader.rebuild({
shader: this.config.shader,
uniforms: this.uniforms,
});
this.config.shader = formatShadertoySource(string);
this.createEditorView();
}
this.shader.rebuild({
shader: this.config.shader,
uniforms: this.uniforms,
});
this.editorView?.setState(
this.createState(this.config.shader, this.uniforms)
);
}
rebuild(sketch: { shader: string; uniforms?: UniformValue[] }) {
const { shader = '', uniforms = [] } = sketch;
this.config.shader = shader;
this.config.uniforms = uniforms;
this.shader.rebuild({
shader,
uniforms,
});
this.editorView?.setState(this.createState(shader, uniforms));
}
setUniform(key: string, value: any) {
this.shader.setUniform(key, value);
}
start() {
this.shader.start();
}
stop() {
this.shader.stop();
}
createState(
shader: string = DEFAULT_FRAGMENT_SHADER,
uniforms: UniformValue[any][] = DEFAULT_UNIFORMS
uniforms: UniformValue[] = DEFAULT_UNIFORMS
): EditorState {

@@ -258,3 +291,5 @@ return EditorState.create({

this.editorView?.destroy();
this.shader?.destroy();
this.container.remove();
}
}

@@ -8,2 +8,7 @@ import Uniform from './Uniform';

import {
type ShaderConfig,
type ShaderState,
type UniformValue,
} from '../types/shader';
import {
DEFAULT_FRAGMENT_SHADER,

@@ -19,22 +24,2 @@ DEFAULT_UNIFORMS,

export interface ShaderConfig {
target?: HTMLElement;
shader?: string;
uniforms?: any[];
width?: number;
height?: number;
fillViewport?: boolean;
dpr?: number;
onSuccess?: Function;
onError?: Function;
animate?: boolean;
debug?: boolean;
}
export interface ShaderState {
active: boolean;
}
export type UniformValue = [string, number, any[]];
const DEFAULT_CONFIG: ShaderConfig = {

@@ -55,3 +40,3 @@ target: document.body,

export default class Shader {
private config: ShaderConfig;
public config: ShaderConfig;
private canvas: HTMLCanvasElement;

@@ -67,2 +52,3 @@ private raf: any;

public volume: number;
private _uniformMap: any;

@@ -125,2 +111,3 @@ constructor(

this.setUniform = this.setUniform.bind(this);
this.raf = raf(this.tick.bind(this));

@@ -153,7 +140,17 @@

get vertexShader(): string {
return `${DEFAULT_DEFS}\n${DEFAULT_UNIFORM_DECLARATIONS}\n${this.uniformDeclarations}\n${GLSL_UTILS}\n${DEFAULT_VERTEX_SHADER}`;
return `
${DEFAULT_DEFS}
${DEFAULT_UNIFORM_DECLARATIONS}
${this.uniformDeclarations}
${GLSL_UTILS}
${DEFAULT_VERTEX_SHADER}`;
}
get fragmentShader(): string {
return `${DEFAULT_DEFS}\n${DEFAULT_UNIFORM_DECLARATIONS}\n${this.uniformDeclarations}\n${GLSL_UTILS}\n${this.config.shader}`;
return `
${DEFAULT_DEFS}
${DEFAULT_UNIFORM_DECLARATIONS}
${this.uniformDeclarations}
${GLSL_UTILS}
${this.config.shader}`;
}

@@ -178,6 +175,22 @@

setUniform(key: string, value: any) {
try {
const index = this._uniformMap[key];
if (this.config.uniforms?.[index][2]) {
this.config.uniforms[index][2] = value;
}
} catch (e) {
console.warn(`Error setting uniform ${key}.`);
}
}
buildUniforms(): UniformValue[] {
const uniforms = [...INTERNAL_UNIFORMS, ...(this.config.uniforms || [])];
return uniforms.reduce((acc, uniform: any) => {
this._uniformMap = this.config.uniforms?.reduce((acc, [name], i) => {
acc[name] = i;
return acc;
}, {});
return uniforms.reduce((acc, uniform: any, i) => {
acc[uniform[0]] = new Uniform(

@@ -271,16 +284,3 @@ this.ctx,

try {
this.ctx?.detachShader(
this.program as any,
this.shaders?.[this.ctx?.VERTEX_SHADER]
);
this.ctx?.detachShader(
this.program as any,
this.shaders?.[this.ctx?.FRAGMENT_SHADER]
);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.FRAGMENT_SHADER]);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.VERTEX_SHADER]);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.FRAGMENT_SHADER]);
this.ctx?.deleteProgram(this.program);
this.destroy({ rebuild: true });
this.program = this.ctx?.createProgram() as any;

@@ -303,2 +303,6 @@ this.compileShader(this.ctx?.VERTEX_SHADER, this.vertexShader);

);
if (this.config.animate) {
this.start();
}
} catch (e) {

@@ -325,5 +329,28 @@ // console.log(e);

destroy() {
destroy({ rebuild = false } = {}) {
if (this.config.animate) {
this.stop();
}
this.ctx?.detachShader(
this.program as any,
this.shaders?.[this.ctx?.VERTEX_SHADER]
);
this.ctx?.detachShader(
this.program as any,
this.shaders?.[this.ctx?.FRAGMENT_SHADER]
);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.FRAGMENT_SHADER]);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.VERTEX_SHADER]);
this.ctx?.deleteShader(this.shaders?.[this.ctx?.FRAGMENT_SHADER]);
this.ctx?.deleteProgram(this.program);
if (rebuild) return;
this.canvas.remove();
window.removeEventListener('resize', this.onWindowResize);
}
}

@@ -118,2 +118,3 @@ export const k_hue = /*glsl*/ `

'attribute',
'bool',
'bvec2',

@@ -120,0 +121,0 @@ 'bvec3',

@@ -51,3 +51,3 @@ export const DEFAULT_VERTEX_SHADER = /*glsl*/ `

export const DEFAULT_DEFS = [
'precision lowp float;',
'precision mediump float;',
'#define PI 3.14159265359',

@@ -57,2 +57,3 @@ '#define TWO_PI 2. * PI',

'#define iResolution resolution',
'#define iMouse vec2(0., 0.)',
].join('\n') as any;

@@ -59,0 +60,0 @@

@@ -1,3 +0,6 @@

export { default as Shader, type ShaderConfig } from './classes/Shader';
export { default as Editor, type EditorConfig } from './classes/Editor';
export { default as Shader } from './classes/Shader';
export { default as Editor } from './classes/Editor';
export * from './types/dimensions';
export * from './types/editor';
export * from './types/raf';
export * from './types/shader';
{
"name": "fragment-shader",
"version": "0.1.3",
"version": "0.1.5",
"description": "A lightweight, performant WebGL fragment shader renderer + editor. ",

@@ -17,3 +17,4 @@ "main": "index.js",

"shader",
"renderer"
"renderer",
"editor"
],

@@ -33,5 +34,3 @@ "author": "Zach Winter",

"@codemirror/view": "^6.12.0",
"codemirror": "^6.0.1",
"fragment-shader": "^0.1.1",
"glslx": "^0.3.0"
"codemirror": "^6.0.1"
},

@@ -38,0 +37,0 @@ "devDependencies": {

# **fragment-shader**
This project owns two primary features: a minimalist shader renderer and a live code editor.
> • `/classes/Shader.ts` – A lightweight & highly performant WebGL fragment shader renderer written in TypeScript.

@@ -30,3 +32,3 @@

> **Note** there are several plugins in modern IDEs (VSCode, etc.) that enable GLSL (shader language) syntax highlighting within template literals by prefacing them with `/*glsl*/` – doesn't seem to work on GitHub though.
> **Note** there are several plugins in modern IDEs (VSCode, etc.) that enable GLSL syntax highlighting within template literals by prefacing them with `/*glsl*/` – doesn't seem to work on GitHub though.

@@ -85,4 +87,6 @@ ### **Bare Bones Implementation**

Or, if you become accustomed to the shader being the first argument of the constructor, you can instantiate this way:
> **Note** If you explicitly set `width` or `height`, the renderer sets `fillViewport` to `false`.
If you become accustomed to the shader being the first argument of the constructor, you can instantiate this way:
```javascript

@@ -100,3 +104,3 @@ import { Shader, type ShaderConfig } from 'fragment-shader';

> **Note** If you set `animate` to `false`, the shader will render its initial frame, but from thereon out you will be responsible for calling the `tick()` method on the Shader if you wish to update it – for example, within a `requestAnimationFrame` loop.
> **Note** If you set `animate` to `false`, the shader will render its initial frame, but from thereon out you will be responsible for calling the `tick()` method on the Shader if you wish to update it – for example, within a `requestAnimationFrame` loop:

@@ -125,4 +129,50 @@ ```javascript

Now that we can easily render shaders in the browser, let's experiment with authoring them too!
### **Uniforms**
We can pass any number of `Uniform` values to our shaders. Uniforms passed to the `Shader` class are automatically injected into our shaders without having to define them explicitly. The renderer expects an array of uniforms, each of type `UniformValue`. The first index (`[0]`) of a `UniformValue` defines its `name`, the second (`[1]`) defines its `type`, and the third (`[2]`) defines its `value`.
> **Note** Please note that uniforms of type `bool` are unique in that their values aren't contained within an array.
```javascript
import { Shader, type UniformValue } from 'fragment-shader';
const zoom: UniformValue = ['zoom', 0, [2.5]];
const color: UniformValue = ['color', 3, [0.8, 0.2, 0.6]];
const warp: UniformValue = ['warp', 1, false];
const shader = new Shader({
shader: /*glsl*/ `
void main () {
gl_FragColor = vec4(color, 1.);
}
`,
uniforms: [zoom, color, warp],
});
```
Types are mapped as follows:
```javascript
const SHADER_TYPE_MAP = {
0: 'float',
1: 'bool',
2: 'vec2',
3: 'vec3',
4: 'vec4',
};
```
### **Updating / Cleanup**
```javascript
// Update a uniform value.
shader.setUniform('color', [0.1, 0.6, 0.9]);
// Rebuild with a new shader.
shader.rebuild({ shader, uniforms });
// Destroy shader instance, elements, and event handlers.
shader.destroy();
```
## **Editor.ts**

@@ -133,13 +183,37 @@

```javascript
import { Editor } from 'fragment-shader';
import { Editor, type EditorConfig } from 'fragment-shader';
const glsl = /*glsl*/ `
void main () {
gl_FragColor = vec4(.8, .2, .7, 1.);
}
`;
const config: EditorConfig = {
shader: /*glsl*/ `
void main () {
gl_FragColor = vec4(.8, .2, .7, 1.);
}
`,
uniforms: []
target: document.body,
width: window.innerWidth,
height: window.innerHeight,
dpr: window.devicePixelRatio,
fillViewport: true,
showLineNumbers: true,
showErrors: true,
onError: () => {},
onSuccess: () => {},
onUpdate: () => {},
};
const editor = new Editor(glsl);
const editor = new Editor(config);
```
( More documentation coming soon! )
An `Editor` shares several `Shader` methods:
```javascript
// Update a uniform value.
editor.setUniform('warp', false);
// Rebuild with a new shader.
editor.rebuild({ shader, uniforms });
// Destroy instance.
editor.destroy();
```

@@ -1,2 +0,2 @@

import type { UniformValue } from '../classes/Shader';
import type { UniformValue } from './shader';

@@ -7,2 +7,11 @@ export interface EditorConfig {

uniforms?: UniformValue[];
showErrors?: boolean;
onError?: Function;
onSuccess?: Function;
onUpdate?: Function;
width?: number;
height?: number;
dpr?: number;
fillViewport?: boolean;
showLineNumbers?: boolean;
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc