npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

w2gl

v0.0.20

Published

javascript micro-library based on three.js that will helping you initialize your shader scene more quickly

Downloads

7

Readme

w2gl.js NPM Package Build Size NPM Downloads Dev Dependencies

javascript micro-library based on three.js that will helping you initialize your shader scene more quickly

english - french

Problem❓

to make a film, a director needs 3 things: a scene, a camera and a monitor. it's exactly the same in the world of shaders. But implementing webgl natively is not an easy task. then it's really not easy to keep the code clean with this api. fortunately, new libraries have already solved this problem. thanks to them! Even though it has become easier to create webgl shaders with these libraries, sur still has to redefine the same instructions before we can have fun with our shaders.

three.js

<!-- source @see https://thebookofshaders.com/04/ -->
<body>
  <div id="container"></div>
  <script src="js/three.min.js"></script>
  <script id="vertexShader" type="x-shader/x-vertex">
    void main () {
      gl_Position = vec4( position, 1.0 );
    }
  </script>
  <script id="fragmentShader" type="x-shader/x-fragment">
    uniform vec2 u_resolution;
    uniform float u_time;

    void main () {
      vec2 st = gl_FragCoord.xy/u_resolution.xy;
      gl_FragColor=vec4( st.x, st.y, 0.0, 1.0 );
    }
  </script>
  <script>
    var container;
    var camera, scene, renderer;
    var uniforms;

    init();
    animate();

    function init() {
      container = document.getElementById( 'container' );

      camera = new THREE.Camera();
      camera.position.z = 1;

      scene = new THREE.Scene();

      var geometry = new THREE.PlaneBufferGeometry( 2, 2 );

      uniforms = {
          u_time: { type: "f", value: 1.0 },
          u_resolution: { type: "v2", value: new THREE.Vector2() },
          u_mouse: { type: "v2", value: new THREE.Vector2() }
      };

      var material = new THREE.ShaderMaterial( {
          uniforms: uniforms,
          vertexShader: document.getElementById( 'vertexShader' ).textContent,
          fragmentShader: document.getElementById( 'fragmentShader' ).textContent
      } );

      var mesh = new THREE.Mesh( geometry, material );
      scene.add( mesh );

      renderer = new THREE.WebGLRenderer();
      renderer.setPixelRatio( window.devicePixelRatio );

      container.appendChild( renderer.domElement );

      onWindowResize();
      window.addEventListener( 'resize', onWindowResize, false );

      document.onmousemove = function(e){
        uniforms.u_mouse.value.x = e.pageX
        uniforms.u_mouse.value.y = e.pageY
      }
    }

    function onWindowResize( event ) {
      renderer.setSize( window.innerWidth, window.innerHeight );
      uniforms.u_resolution.value.x = renderer.domElement.width;
      uniforms.u_resolution.value.y = renderer.domElement.height;
    }

    function animate() {
      requestAnimationFrame( animate );
      render();
    }

    function render() {
      uniforms.u_time.value += 0.05;
      renderer.render( scene, camera );
    }

Solution❓

and if you stop implementing the same instructions to start a project every time. as a 3d developer, you are going to need assistance, you need a safe guy who will take care of your back, who will take care of the boring tasks that you don't want to repeat anymore. this guy may be w2gl. written in javascript this micro-library based on 3d engine libraries will allow you to have fun quickly with the obscure universe of shaders. note that w2gl is not there to replace the role of these libraries, it is a little overlay on these libraries which will precisely prepare your 3d scene and give you some super powers through a starter object.

w2gl.js

const starter = w2gl.init( {
  THREE,
  shader: {
    myShaderName : {
      vertex: `
        void main () {
          gl_Position = vec4(position, 1.0);
        }
      `,
      fragment: `
        uniform vec2 resolution;
        uniform float time;

        void main () {
          vec2 st = gl_FragCoord.xy / resolution.xy;
          gl_FragColor=vec4(st.x, st.y, 0.0, 1.0);
        }
      `
    }
  }
} );

starter.events.onresize( starter.screen.resize );
starter.events.onmousemove( starter.mouse.move );

⚠️ Disclaimer

i'm not a developer, i'm just a normal guy who likes programming with the desire to learn more about the dark side of force. last points, changes will be coming in the future for the good of all, i hope.

📦 Install dependencies

Command line

npm i w2gl

OR

yarn add w2gl

Download

you can also download the project, after recover the file in dist/w2gl.js and then add it in the folder of your project in which you store the external libraries to your development.

🚀 Start project

are you looking to create a scene quickly? If your answer is yes, you should try this!

1. es6

import * as THREE from 'three';
import w2gl from 'w2gl';
import vertex from './shader/vertex.fs';
import fragment from './shader/fragment.fs';

// 1. first way, to obtain the starter object provided by the result of the init method
const starter = w2gl.init( { THREE, shader: { myShaderName : { vertex, fragment } } } );

console.log( starter ); // <-- et hop! w2gl is available

// 2. second way, to obtain the starter object provided by the callback function, pass as the second argument of the init method
w2gl.init( { THREE, shader: { myShaderName : { vertex, fragment } } }, starter => {

  console.log( starter ); // <-- voilà! w2gl is ready in the callback scope only

} );

2. html/javascript

<script src="./src/three.js"></script>
<script src="./src/w2gl.js"></script>

<script id="vertexShader" type="x-shader/x-vertex">
  void main () {
    gl_Position = vec4( position, 1.0 );
  }
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
  uniform vec2 resolution;
  uniform float time;

  void main () {
    vec2 st = gl_FragCoord.xy/resolution.xy;
    gl_FragColor=vec4( st.x, st.y, 0.0, 1.0 );
  }
</script>

<script>
  // 1. first way, to obtain the starter object provided by the result of the init method
  var starter = w2gl.init( {
    THREE,
    shader: {
      vertex: document.getElementById( 'vertexShader' ).innerHTML,
      fragment: document.getElementById( 'fragmentShader' ).innerHTML
    }
  } );

  console.log( starter ); // <-- et hop! w2gl is available

  // 2. second way, to obtain the starter object provided by the callback function, pass as the second argument of the init method
  w2gl.init( {
    THREE,
    shader: {
      vertex: document.getElementById( 'vertexShader' ).innerHTML,
      fragment: document.getElementById( 'fragmentShader' ).innerHTML
    } 
  }, starter => {
  
    console.log( starter ); // <-- voilà! w2gl is available and scoped
  
  } );
</script>

📖 API

  • .init( option )

    the init method takes as an input argument: option.

    params

    option { Object }: collection.

    example

    see the option schema

  • starter

    it's a collection of methods that will help you during the development of your shaders. It contains everything you need to focus on your main task.

    example
    {
      THREE: {ACESFilmicToneMapping: 5, AddEquation: 100, AddOperation: 2, AdditiveBlending: 2, AlphaFormat: 1021, …}
      shader: {myShaderName: S}
      scene: {current: ob}
      camera: {current: db}
      renderer: {current: og}
      events: {onmousemove: ƒ, onresize: ƒ, clear: ƒ, init: ƒ, mousemove: ƒ, …}
      mouse: X {x: 5, y: 382, move: ƒ}
      screen: ea {width: 1306, height: 460, resize: ƒ}
    }
    • .shader

      the shader object returns THREE.Mesh created from PlaneBufferGeometry and ShaderMaterial. This is the one that contains your vertex shader and your shader fragment as well as the uniforms.

      uniforms

      to save time, I have already implemented basic uniforms.

      example
      // fragmentShader.fs || vertexShader.vs
      
      uniform vec2 mouse;
      uniform vec2 resolution;
      uniform float time;
      // index.js
      starter.shader.myShaderName.material.uniforms
      
      /* output:
      
      {
        mouse: {type: "v2", value: new THREE.Vector2()}
        resolution: {type: "v2", value: new THREE.Vector2()}
        time: {type: "f", value: 0.0}
      }
      
      */
    • .scene

      the scene object returns THREE.Scene(). This scene is the 3d space in which your mesh will be.

    • .camera

      the scene object returns THREE.Camera(). A basic camera without artifice that you don't need to initialize.

    • .renderer

      the scene object returns THREE.WebGLRenderer(). I have it a little custom at once, so that it can increment the value of timer.time within the rendering loop.

    • .events

      i have made available to you methods that you can use as event listeners to update your scene. indeed each of these methods are executed in the event listener corresponding to its name.

      • onmousemove( f )

        this method is called when the mouse is moving on the screen. You can retrieve the window object directly and then update your fragment shader only when a movement of the mouse is detected.

        arguments

        f { Function }: callback. returns { Void }: undefined.

        explanation

        onmousemove => execute in the event listener callback window.addEventListener( 'mousemove', _ => {}, false );

        example
        starter.shader.myShaderName.onmousemove( event => {
        
          starter.shader.myShaderName.material.uniforms.mouse.value.x = event.clientX;
          starter.shader.myShaderName.material.uniforms.mouse.value.y = event.clientY;
        
        } );
      • onrender( f )

        this method is executed in a requestAnimationFrame. onrender is called with as input argument a timer object which will allow you to update your shader fragment.

        arguments

        f { Function }: callback. returns { Void }: undefined.

        explanation

        onrender => executed in the setAnimationLoop method.

        example
        starter.shader.myShaderName.onrender( timer => {
        
          starter.shader.myShaderName.material.uniforms.time.value += timer.time;
        
        } );
      • onresize( f )

        this method is called when the dimensions of your screens have changed, an event argument is passed to it that you can use to update the resolution of your fragment shader only when a screen change has been detected.

        arguments

        f { Function }: callback. returns { Void }: undefined.

        explanation

        onresize => execute in the event listener callback window.addEventListener( 'resize', _ => {}, false );

        example
        starter.renderer.current.onresize( event => {
        
          starter.renderer.current.setSize( event.target.innerWidth, event.target.innerHeight );
        
        } );
    • .mouse

      contains new Mouse () which is nothing more than a simple two-dimensional vector. so you don't need to implement it anymore. It is accessible via the starter object. once initialized. You will have access to its positions x, y.

      example
      starter.mouse
      
      // output {x: 0, y: 0, move: ƒ}
      
      starter.events.onmousemove( starter.mouse.move );
      
      // the mouse is initialized to update each time the onmousemove event is called.
    • .screen

      it is the screen component, it contains the screen dimension and a resize function that you can call to though the starter.events.onresize.

      example
      starter.screen
      
      // output {width: 343, height: 811, resize: ƒ}
      
      starter.events.onresize( starter.screen.resize ); 
      
      // the screen is initialized to be set each time the onresize event is called.

🚨 Tests

Running

reports

npm run test:reports

OR

yarn test:reports

watch

npm run test:watch

OR

yarn test:watch

📝 Todo

  • [ ] supports glsl #include
  • [ ] more events
  • [ ] documentation
  • [x] mode by default
  • [ ] improve test cases

📁 Source

©️ License

Copyright ©️ 2019 monsieurbadia

Released under the MIT license

🙏 Supports

logo by @mllemartins with 🖤
built by @monsieurbadia with 🖤

⭐️ this repository if this project helped you!