Giter VIP home page Giter VIP logo

interactive-shader-format-js's Introduction

ISF-JS-Renderer

Renders ISF Effects and Compositions into a canvas

http://www.interactiveshaderformat.com/

Example

var gl = canvas.getContext("webgl");

// Instantiate the renderer with your webgl context
var renderer = new ISFRenderer(gl);

// Load up the source
renderer.loadSource(fragmentISF, optionalVertexISF);

// Set up any values passing either numbers, arrays of numbers, or image/video elements
renderer.setValue("someInput", someValue);
// If you pass any image/video elements, you need to call `pushTextures` after to pass the images to webgl
renderer.pushTextures();

// Draw it into the canvas
renderer.draw(canvas);

Raw ISF Parsing

Use the ISFParser class to parse ISF Fragment and Vertex shaders to GLSL shaders and an input data-mapping.

var parser = new ISFParser();
parser.parse(fragmentISF, optionalVertexISF);
console.log(parser.fragmentShader, parser.vertexShader, parser.inputs);

Building

Build with browserify

npm install -g browserify
browserify main.js -o build/main.js

or

npm install -g watchify
watchify main.js -o build/main.js

interactive-shader-format-js's People

Contributors

2xaa avatar cale-bradbury avatar jeromeetienne avatar msfeldstein avatar timpietrusky avatar wgoldie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

interactive-shader-format-js's Issues

Diagnosing "Something is wrong with your metadata at position NaN and line 1"

const position = parseInt(tokens[tokens.length - 1], 10);

This function doesn't appear to be portable - the error message that JSON.parse spits out isn't standardized.

In Chromium I get "Unexpected token a in JSON at position 175" which results in the correct behavior.

In Firefox I get "JSON.parse: expected double-quoted property name at line 37 column 30 of the JSON data". Here the attempt to extract the position fails.

Buffer Error

I've followed the simple example of the README, but buffers don't seem to be working.
This is probably just in my implementation, however as there are no examples for me to check against, it's very difficult to diagnose if the problem is my implementation or the library itself.

More simple shaders without buffers seem to work fine.

I've tried using this demo shader (the website looks like it's using this library):
https://www.interactiveshaderformat.com/sketches/326

But I get:

[.Offscreen-For-WebGL-0000029B7DE2FB20]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
localhost/:1 [.Offscreen-For-WebGL-0000029B7DE2FB20]RENDER WARNING: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
localhost/:1 [.Offscreen-For-WebGL-0000029B7DE2FB20]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glDrawArrays: framebuffer incomplete

The first error seems strange as I'm supplying a suitable canvas to the draw function.
GLSL (es300 at least) doesn't much care about power of two anymore I thought? Unless framebuffers are different? I'm not used them much in the past.

The second error I assume is linked to the first, however I don't know for sure.

Thanks for your work on this library, I'd love to contribute at some point.

mathjs is way overkill

we're using math.js library to run the simplest of equations in ISFRenderer.evaluateSize, and it's causing massive bloat because it requires crypto libraries. Lets not depend on this huge library.

Chain together shaders?

The code is fantastic to be able to utilize ISF shaders in js. Really happy to have found this. I'm trying to figure a way to combine shaders on top of a single web cam / video texture. Tried something like the bottom but doesn't seem to want to render
Any ideas? Would love to add and fork if I could get this working.

   const ISFRenderer = require('../dist/build.js').Renderer;

let video = null;

init();



async function loadFile(src, callback) {
  const response = await fetch('examples/' + src);
  const body = await response.text();

  callback(body);
}

function init(){
  
  console.log("successful load!");

  // video // 

	video = document.createElement('video')
	video.autoplay = true

	navigator.mediaDevices.getUserMedia({
	video: true
	}).then(function(stream){
	video.srcObject = stream        
	})

  // canvas //

	const container = document.createElement('div');
	const canvas = document.createElement('canvas');

	container.style.position = 'relative';
	container.appendChild(canvas);

	canvas.width = window.innerWidth / 2;
	canvas.height = window.innerHeight / 2;
	document.body.appendChild(container);

	const gl = canvas.getContext('webgl2');

	// ISF //

    createRendering('dot.fs', 'dot.vs', gl, canvas, video, false); // fsFile, vsFile, ctx, teture, draw boolean

    const tex = new THREE.Texture(canvas);
  	tex.needsUpdate = true
    tex.flipX = false
    tex.flipY = false

    createRendering('feedback.fs', undefined, gl, canvas, tex, true);

}



function createRendering(fsFilename, vsFilename, ctx, _canvas, _input, toggleDraw) {

  let fsSrc;
  const fsLoaded = (response) => {
    fsSrc = response;

    if (vsFilename) {
      loadFile(vsFilename, vsLoaded);
    } else {
      vsLoaded();
    }
  }

  const vsLoaded = (vsSrc) => {
   
    const renderer = new ISFRenderer(ctx);
	renderer.loadSource(fsSrc, vsSrc);

    const animate = () => {
      requestAnimationFrame(animate);

      // tapestryfract doesn't have inputImage so we'll need to check
      // if ('inputImage' in renderer.uniforms) {

        renderer.setValue('inputImage', _input);
      // }
      if (toggleDraw) { 
      		renderer.draw(_canvas);
  		}
    };

    requestAnimationFrame(animate);
   }

  loadFile(fsFilename, fsLoaded);
}

Add UMD/global/worker scope build

Adding a UMD/global/worker scope build of the library (i.e. a version of the ISF library which doesn't rely on the DOM/window being present) will allow use of the ISF library in a WebWorker, allowing OffscreenCanvas support.

This is important for OffscreenCanvas related performance gains and will extend the functionality of this library greatly and close #16.

Either we can find a way to support this using browserify or alternatively I can easily set up a compatible Webpack build which can build to multiple targets.

I don't have a lot of Browserify experience and my attempt of building the library with the --standalone Browserify flag didn't work. Math.JS seems to be a problem.

Are we able to remove Math.JS? #3.

Setting renderer.setValue('inputImage', image) results in black image

I've been trying to use ISF on stackblitz.
You can see my code here: https://stackblitz.com/edit/typescript-akptnb?file=index.ts

It seems like the Renderer works as it adds the shader to the canvas, but the image doesn't appear.

I tried to run this repository locally with the webcam started, but I'm getting the same result.

Screenshot:
Screenshot 2019-08-27 at 12 34 31

I hope someone can help me as i really like this library and it's simplicity :)

All the best,
Emil

how to use without node?

Hey there, wondeful library. I love the format and how it works with VDMX.

I was able to run the server in the examples using budo however, I would like to use the library without node, locally with one js file. What is the best way to do this? Or is it not recommended as node is doing some sort of heavy lifting that would not work well on the client side?

Thank you

OffscreenCanvas support

No idea if this is the proper way of doing things, but it gets the job done.

I'll make a PR tonight, but these are my edits - just in case.

ISFRenderer.prototype.pushTexture = function pushTexture(uniform) {

ISFRenderer.prototype.pushTexture = function pushTexture(uniform) {
  if (!uniform.value) {
    return;
  }

  let flip = false;

  if (
    uniform.value.constructor.name !== "OffscreenCanvas" &&
    (
      uniform.value.tagName !== 'CANVAS' &&
      !uniform.value.complete &&
      uniform.value.readyState !== 4)
    ) {
    return;
  }

  if (uniform.value.constructor.name === "OffscreenCanvas") {
    uniform.value = uniform.value.transferToImageBitmap();
    flip = true;
  }

  const loc = this.program.getUniformLocation(uniform.name);
  uniform.texture.bind(loc);
  this.gl.texImage2D(
    this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, uniform.value);
  if (!uniform.textureLoaded) {
    const img = uniform.value;
    uniform.textureLoaded = true;
    const w = img.naturalWidth || img.width || img.videoWidth;
    const h = img.naturalHeight || img.height || img.videoHeight;
    this.setValue(`_${uniform.name}_imgSize`, [w, h]);
    this.setValue(`_${uniform.name}_imgRect`, [0, 0, 1, 1]);
    this.setValue(`_${uniform.name}_flip`, flip);
  }
};

FLOAT pass target isn't working

I'm trying to use a FLOAT render target:

/*{
    "ISFVSN": "2",
    "INPUTS": [],
    "PASSES": [
        {
            "TARGET": "pass0",
            "FLOAT": true
        },{
            "DESCRIPTION": "Render"
        }
    ]
}*/

void main() {
    if (PASSINDEX == 0) {
		gl_FragColor = vec4(1,0,0,1);
    } else {
    	gl_FragColor = IMG_NORM_PIXEL(pass0, gl_FragCoord.xy / RENDERSIZE);
    }
}

This shows a black screen, removing the FLOAT shows a red screen.

Create a cleaner api

make private methods actually private and make it clear what the public api is from looking at the source

Offscreen destination isn't possible

When using a canvas which hasn't been placed in the DOM, the library freaks out and breaks.
This is because offsetWidth and offsetHeight have no value.

evaluateSize in ISFRenderer currently expects the destination to be part of the DOM, which isn't always the case.

Pull request incoming.

Regex hangs the browser

const results = regex.exec(rawFragmentShader);

I'm trying to run some non-ISF shaders through the parser which cause this line to hang the browser. Instead of doing this validity check and grabbing the metadata block with an expensive regex, why not use the startIndex and endIndex endpoints you define later?

If you're wondering why I'm trying to parse non-ISF shaders, consider a live-update application where someone makes a typo, or in my case where I'm supporting multiple shader metadata formats, and only want to invoke ISF if it's a valid ISF shader.

Roadmap ideas for ISF v3

I forked the repo today, have some big plans in the works to grow ISF:

Gather vs and fs into one '.isf' file ( I notice many times I copy only the fs and get errors, also this seems more elegant as well as descriptive and searchable )

Make vertex pass more useful: reference vertexshaderart.com:
https://github.com/greggman/vertexshaderart
so much can be done and very computationally efficient. Requires gl_vertexID input, opengl rendermodes, and point size. Creates particles and geometry that is quick and powerful.

Compatibility / tie in with shaderfrog, I showed him your spec as a solution to what he is doing and to facilitate fluid compatibility with three.js

Update ShaderToy API import : plan to have a meeting with him to see if we could set up a more direct compatibility, and am experimenting with my own solutions at the moment via their API json files and regex.

A few months back, before I discovered ISF, I was creating a simple and elegant solution to the same thing that parses any glsl shader and defines controls and passes based on the uniforms. I plan to put this up on a github repo very soon, it provides immediate compatibility with any GLSL file and I and am exploring options to merge that into ISF.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.