GithubHelp home page GithubHelp logo

yanchith / webglutenfree Goto Github PK

View Code? Open in Web Editor NEW
8.0 2.0 1.0 27.89 MB

We serve your draw calls type-safe and gluten-free

Home Page: https://yanchith.github.io/webglutenfree/

License: MIT License

JavaScript 1.37% TypeScript 98.63%
typescript gluten-free computer-graphics stateless webgl webgl2

webglutenfree's Introduction

webglutenfree

Build Status

We serve your draw calls type-safe and gluten-free.

Webglutenfree is a lightweight, comfort focused abstraction on top of WebGL2. It abstracts away state manipulation, uses parameters instead of state-setting calls, and encapsulates all GPU resident resources within helpful handles.

On the scale from low-level and flexible to high-level and opinionated, Webglutenfree leans towards flexibility. In general, 80-90% of the sensible things possible with raw WebGL should be possible to do. If you are missing a feature, please file an issue.

However, the library is opinionated in the sense that some things are just "not a good idea" and strives to make invalid operations unexpressable both via compile time checks and runtime assertions (the latter in dev mode only).

While it can be consumed directly from JavaScript, using TypeScript adds compile time safety in terms of value dependent type parameters. For instance, it won't allow you to store Float32Array data in a texture with RGBA32UI internal format.

Current State

We want to get to a 0.1.0 (meaning generally usable) eventually, but there are still things missing:

  • Documentation: we need a tutorial and API documentation,
  • API stability: the API is still in flux,
  • Features: we are missing at least Cubemaps, Texture Arrays, and Renderbuffers.

Gallery

Have a look at our gallery (For the moment the gallery works only on browsers supporting both WebGL2 and ES modules, e.g. Firefox and Chrome)

Hello Triangle

Usually, you would acquire a Device (WebGL context) and create Commands at init time. To draw, request a render target from the device and execute draw commands with it.

import { Device, ElementPrimitive } from "webglutenfree";

const dev = Device.create();
const cmd = dev.createCommand(
    `#version 300 es
    precision mediump float;

    layout (location = 0) in vec2 a_position;
    layout (location = 1) in vec4 a_color;

    out vec4 v_color;

    void main() {
        v_color = a_color;
        gl_Position = vec4(a_position, 0.0, 1.0);
    }
    `,
    `#version 300 es
    precision mediump float;

    in vec4 v_color;

    layout (location = 0) out vec4 f_color;

    void main() {
        f_color = v_color;
    }
    `,
);

const attrs = dev.createAttributes(ElementPrimitive.TRIANGLE_LIST, {
    0: [
        [-0.3, -0.5],
        [0.3, -0.5],
        [0, 0.5],
    ],
    1: [
        [1, 0, 0, 1],
        [0, 1, 0, 1],
        [0, 0, 1, 1],
    ],
});

dev.target((rt) => {
    rt.draw(cmd, attrs);
});

Triangle

Installation

npm install --save webglutenfree or yarn add webglutenfree

Development

First time setup:

Install node and yarn, e.g. with Volta (volta pins are saved in package.json).

Developing

  • Run yarn to install libraries,
  • Run yarn serve to run a local server with the project,
  • Run yarn build to build the project,
  • Run yarn build-all to build the project for all targets,
  • Run yarn test to run tests (must be built first: yarn build or yarn compile),
  • Run yarn lint to run a linter on the project source.

Sources

Webglutenfree is inspired by:

We found the following docs and tutorials helpful:

webglutenfree's People

Contributors

dependabot[bot] avatar ondrowan avatar yanchith avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

ondrowan

webglutenfree's Issues

Add AttributeLocation and remove Command.locate()

Allow caching queried attribute locations with AttributeLocation:

const cmd = ...;
const aPosition = dev.queryAttributeLocation(cmd, "a_position");
const aColor = dev.queryAttributeLocation(cmd, "a_color");

// .index property allows for getting the location
const positionLocation = a_position.index;

// toString() allows for use in computed properties
const attrs = dev.createAttributes(Primitive.TRIANGLES, {
  [aPosition]: [
        [-0.3, -0.5],
        [0.3, -0.5],
        [0, 0.5],
    ],
  [aColor]: [
        [1, 0, 0, 1],
        [0, 1, 0, 1],
        [0, 0, 1, 1],
    ],
});

After implementing we can remove Command.locate() and migrate all examples to use this.

Sharing GL context with three.js

Hi.

I'm trying to incorporate webglutenfree into a big three.js-based app. Both libs need to share the same GL context.
Three.js can reset its internal state, but I see no way to do so in webglutenfree.
In three.js I can do:

threeInstance.state.reset();

And that will cause three.js to bind programs, uniforms etc. again.
There needs to be something like that on webglutenfree side as well.

Add tests

All non WebGL functionality should have unit tests. WebGL could be tested by mocking the context.

Investigate --preserveConstEnums

To support plain javascript, we are not using const enums, increasing our code size footprint. With --preserveConstEnums, we could allow typescript users to optimize bundle size.

The enum objects would still be present in our dists for javascript projects, but typescript projects would inline enum values from d.ts, making the imported enum objects eligible for DCE during bundling.

Needs investigation whether typescript actually performs the inlining from d.ts as it may classify as type directed emit, which they don't do.

Website

As a preparation for adding docs to the website we should add some build tooling around the current gallery (currently completely static and residing in the docs dir) so it can start to slowly evolve towards a general website.

It should bundle webglutenfree and monaco as standard dependencies and only load the actual examples dynamically. Bundling monaco might require webpack ๐Ÿ™

Review allocations

We would like to support applications that try to avoid memory pressure, therefore we should not make unneeded allocations and buffer copies all over the place.

There are probably two classes of allocations happening right now:

  • const foo = bar || {}
  • buffer conversions, e.g. new Uint8Array([1, 2, 3])

Spawning new empty objects theoretically could be fine, as long as the particular vm has a generational gc, these objects should be very cheap to create and destroy (needs verifying). In any case, we can live without some js conveniences if it provides better experience overall.

Buffer conversions are more tricky. WebGL always requires data in a typed array format. Currently we try to not do needless conversions, but there are a few [] to typed array conversions which do copy data. We should probably remove buffer copying from those that are expected to be called often or in the rendering loop, e.g. VertexBuffer.store(). It also may make sense to create a separate higher-level API and make the current API strictly low-overhead.

Change API to be tree-shaking friendly

Currently rollup does not attempt to prune class methods due to the dynamic nature of the language, and it seems that even if it did, it would have to be really conservative about it (rollup/rollup#349). This means that our current API does not tree-shake well: Device is a class with a lot of methods that utilize imports from the rest of the library.

This is what the API could look like with plain functions:

import * as gf from "webglutenfree"

const dev = gf.createDevice(); // or gf.createDevice(canvas) or gf.createDevice(gl)
const cmd = gf.createCommand(dev, vertexShader, fragmentShader, options);
const attrs = gf.createAttributes(dev, primitive, attributeData);
gf.target(dev, (rt) => {
    gf.draw(rt, cmd, attrs);
});

We could potentially keep methods that don't make use of imports, or move everything into functions for more consistency.

Investigate WebGL1 support

There could theoretically be support for WebGL1 with some required extensions (VAOs).

  • How would this change the API?
  • Can we support all features, or would some capabilities need to be disabled for WebGL 1 mode?
  • Can #version 300 es be supported?

This can only be considered a win when the user doesn't need to know, whether he is using WebGL 1 or 2 under the hood. Also, need for this will disappear with time.

Prepare for 0.1.0

After 0.1.0 there should be significantly less API churn, but we need to implement more features before stabilizing anything - to find out what the "final" API looks like. Apart from features and API changes, we need better test coverage and documentation.

We need at least:

  • Cubemaps (#19)
  • Renderbuffers (#18)
  • Decent test coverage (#26)
  • Document all public APIs (#24)
  • Add tutorial examples
  • Improve showcase examples
  • Document all examples (#25)
  • Website with API docs (#39, #40)
  • API cleanup
    • After implementing Cubemap and Renderbuffer decide, whether uniforms and textures should really be separate
      • Nope, the implementation can tell them apart, no need to separate them in the API. This also plays well with the new uniform types introduced in the Cubemap branch
    • Replace Command.locate() with AttributeLocation (#36)
    • Decide the "enum hierarchy".
      • Enums are per use-case and there is no hierarchy as a result of #17
    • Investigate making the library tree-shaking friendly (#53)
      • Won't be happening for 0.1.0, but may revisit later

Add TextureArray

TextureArrays enable binding multiple textures at once, lessening the need for texture atlases.

Support multiple Buffers sources for Attributes (both interleaved and packed)

Currently, we can only pass in one buffer per attribute, but it is often desired to have multiple data sources in a single buffer, e.g. by interleaving values [position, color, position, color, ...].

WebGL let's the user control this via stride and offset parameters to gl.vertexAttribPointer(). Since we already expose other parameters to gl.vertexAttribPointer(), we can expose these two as well.

Also note that currently it is possible to pass a number[] as buffer in AttributePointerConfig. This must be disallowed since it would silently upload the same vertex buffer multiple times. This is no longer possible to do, so we should be good.

Add Cubemap

Cubemaps enable skyboxes and environment mapping. Implementation-wise, Cubemap should probably be a separate object from Texture, because it supports a slightly different operations, but also mirror its implementation. Would be nice to also add an example, while we are at it.

Assert all inputs

We currently rely on TS to remove a whole class of invalid input values. We would like to have better support for JS consumers via having more complete input assertions with good error messages.

The downside is increased maintenance burden associated with keeping the asserts (and their tests) in sync with types, but there already need to be some run-time assertions for cases we can't check with types.

Add Renderbuffer

WebGLRenderbuffers are the only way to support multisampling and postprocessing at the same time. The implementation should mirror Texture where possible. Examples could also be updated to use Renderbuffer where appropriate.

Split off scripts to subfolder

To prevent conflating @types dependencies between scripts and the library itself, split off scripts to its own subproject (with own package.json).

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.