Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Functional GLSL Linker

License

NotificationsYou must be signed in to change notification settings

unconed/shadergraph

Repository files navigation

Functional GLSL linker

Shader Graph

ShaderGraph is a library for linking together GLSL snippets into stand-aloneshaders. It is mainly meant to build complicated shaders 100% programmatically.But it can also act as the back-end to a live graph-based shader editor, as itsgraph model is persistent.

Snippets can be simple one-liners, or multi-function source files. Snippets canalso declarecallbacks, as functions without bodies, linked in from elsewhere.This allows complicated execution flows to be built very easily.

vec3getColor();voidmain() {gl_FragColor=vec4(getColor(),1.0);}

ShaderGraph is designed to play well with Three.js, but does not depend on it.It merely follows the same code/object conventions.

There is no editing UI included, only a way to display a graph as anHTML/CSS/SVG diagram.


Live Examples

ShaderGraph

ShaderGraph 2 drives all shaders in MathBox² (in development). For more info,see the articles on acko.net:

Here's a real-world vertex shader for a line primitive, sampling color andposition from two textures:

MathBox 2 - Audio Visualizer example

You can also use ShaderGraph's graph visualizer directly for other purposes:

Basic Use

Install via npm:

npm install shadergraph

Includebuild/shadergraph.js.

To use ShaderGraph, you initialize it once with a given snippet library. Asnippet library is either a dictionary of named snippets, or a fetch function.

// Dynamic fetchvarfetch=function(name){return"...";};// Static fetchvarfetch={getColor:"...",setColor:"...",getRampColor:"...",};varshadergraph=ShaderGraph.load(fetch);

You can use the chainable Factory API to build graphs. It's a smart wrapperaround a partially built graph. It allows you to make splits and joins, hook upcallbacks via requires, import other factories, etc.

Instead of including snippets by name, you can also pass in GLSL code directlyto.pipe(…) and.require(…) regardless of whether you are using a fetchfunction/library or not.

Snippets are instanced by default, letting you bind unique uniforms to specificsnippets in the chain:

Uniform example

// Prepare new shadervarshader=shadergraph.shader();// Prepare uniform (three.js style)varuniforms={diffuseColor:{type:"v3",value:{x:0.5,y:0.75,z:1.0}},};// Build shader graphshader// Require a callback.require("getRampColor")// Build two-step chain that uses the callback and the uniform.pipe("getColor",uniforms).pipe("setColor");varprogram=shader.link();

Instancing behavior can be configured globally or per shader (see below).

Materials

ShaderGraph also includes a material helper, to build a vertex/fragment shadersimultaneously:

Material example

// Prepare new material (vertex + fragment shader)varmaterial=shadergraph.material();// Build vertex shader graphmaterial.vertex.pipe("vertex");// Build fragment shader graphmaterial.fragment.pipe("getColor").pipe("setColor");// Link both shaders and combine into a three.js style materialvarprogram=material.link();

The returnedprogram object is compatible with Three.js'ShaderMaterialobjects.

Caveats

  • Callshadergraph.inspect(…) anywhere to insert an inspector for a graph,and find missing/wrong connections.
  • Preprocessing directives like#ifdef and#define are ignored, but do passthrough. Be careful when using them. Consider using snippets and/or callbacksinstead.
  • Structs are not supported,glsl-parser seems to choke on them. Array typesare probably a bit buggy still.

Reference

Constructor

varfetch=function(name){return};varfetch={name:"...",name:"..."};varconfig={globalUniforms:false,// Make uniforms   globalglobalVaryings:true,// Make varyings   globalglobalAttributes:true,// Make attributes globalglobals:[],// Make specific symbols globalautoInspect:false,// Pop-up a graph inspector if compilation fails}shadergraph=ShaderGraph.load(fetch,config);

ShaderGraph

  • .shader(config = {})

    Returns an emptyshader graph wrapped in a factory. Override globalconfig options.

  • .material(config = {})

    Returns an emptymaterial wrapping two factories:material.vertex andmaterial.fragment. Override globalconfig options.

  • .visualize(graph/factory/material)

    Draw the given graph(s), returns an HTMLelement. Callelement.update() after inserting.

  • .inspect(graph/factory/material)

    Draw the graph and insert it into the body as a floating inspector.

Factory

  • .pipe(name/code, uniforms = {}, namespace = null, defines = {})
    .pipe(name/code, namespace = null, uniforms = {}, defines = {})
    .pipe(name/code, uniforms = {}, defines = {})
    .pipe(factory)

    Add the given code/snippet/factory to the graph and connect it to what came before. Binds dictionary ofuniforms. Set thenamespace.

    Connections are made first between connectors of the same type and name, and then between connectors of the same type (in the order specified in the shader). Any callbacks previously added to the graph are also connected, if possible.

    Pipe example

  • .require(name/code, uniforms = {}, namespace = null, defines = {})
    .require(name/code, namespace = null, uniforms = {}, defines = {})
    .require(name/code, uniforms = {}, defines = {})
    .require(factory)

    Add the given code/snippet/factory to the graph as a callback for what comes next. Binds dictionary ofuniforms. Set thenamespace.

    Require example

  • .isolate().….end()

    Create a finished, isolated subgraph and add it to the graph.

    This is useful, for example, to force the attaching of callbacks to a subgraph:

    varshader=shadergraph.shader();shader.require("getColor");// Require two instances of callbackshader.require("getColor");shader.isolate();shader.require("getColorSum");// Define callback with two open callback inputsshader.end();// Hook up both callbacksshader.pipe("setColor");// Connect to main snippet

    Isolate example

  • .callback().….end()

    Create an isolated subgraph and add it to the graph as a callback.

    Callback example

  • .split().….next().….end()

    Create two or more branches and split connections across them 1-to-1. Connectors which are connected to a branch will not be available for any subsequent branch.

    Split example

  • .fan().….next().….end()

    Create two or more branches and fan connections across them 1-to-N. All connectors are available in each branch.

    Fan example

  • .pass()

    Use this instead of.end() to make additional passthrough connections that skip the entire block. In other words, all connectors at the beginning of the branch will be available again for subsequent nodes.

    Pass example

  • .graph()

    Finalize the graph and return it. The factory is reset to an empty state.

  • .compile(name)

    Finalize the graph and compile it immediately (no callbacks). Returns a GLSL shader string. The factory is reset to an empty state.

  • .link(name)

    Finalize the graph and link it with its subgraphs immediately (with callbacks). Returns a complete GLSL shader string with a main function. The factory is reset to an empty state.

Graph

  • .compile(name)

    Compile the graph (no callbacks). The graph is retained.

  • .link(name)

    Compile and link the graph and its subgraphs (with callbacks). The graph is retained.

Material

  • .link(options = {})

    Link the material's vertex and fragment shader. Returns Three.js style ShaderMaterial options, merged with any existing options passed in.

Manual Use

If you want to build graphs by hand instead of with factories, this is possible,but not as nice. You will need to construct objects and inject a fewdependencies. Use the Factory API as a guide.

The underlying namespaces are exposed asShaderGraph.Graph,ShaderGraph.Block, …Block and its subclasses are the logical pieces of theshader. Each block has aNode associated with it that lives in theGraph andcontains a set ofOutlets. Connections can be made node-to-node withnode.connect(node) (auto-matching by name and type), or outlet-to-outlet withoutlet.connect(outlet).

To compile Graphs created without a factory, you will need to call.compile()or.link() on the graph's tail block directly.


Steven Wittens -http://acko.net/

About

Functional GLSL Linker

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors3

  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp