JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 58
  • Score
    100M100P100Q71217F
  • License MIT

primitive builder based on three.js x babylon.js that will help you to created a scene in an intuitive and functional way.

Package Exports

  • d2k

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (d2k) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

d2k.js NPM Package Build Size NPM Downloads Dev Dependencies

Twitter Follow

primitive builder based on three.js x babylon.js that will help you to created a scene in an intuitive and functional way.

english - french

Problems

  • DRY (do not repeat yourself)
  • webgl API too complex to make young people want to pay attention to 3d programming

Solutions

  • automate the creation of primitives
  • automate the composition of the scene
  • create a scene from a JSON file
  • support GLSL x THREE x BABYLON
  • switch between babylon.js and three.js with a single line of code
  • create experimental experience such as being able to make a kind of Object.assign (THREE, BABYLON), which would give a single canvas the possibility of displaying the two scenes simultaneously on the screen

Getting Started

before you start be sure that your project include three.js and / or babylon.js, once it's good for you, you can install d2k via your shell.

examples (jsfiddle)

using shader - using three.js - using babylon.js - layerization (three.js x babylon.js) - hello world

Install

shell

npm i d2k

OR

yarn add d2k

alternative

download the project, copy the file d2k.js which is located in the folder /dist then you are free to install it in the place provided for this purpose in your application. now you have to import d2k into your module or into your html page and follow this syntax.

ecmascript

import d2k from 'd2k';
import * as THREE from 'three';

window.addEventListener( 'DOMContentLoaded', _ => {

  const THREEstarter = d2k
    .onstarter( { canvas: 'myCanvasId' } )
    .use( THREE )
    .withScene( { name: 'mySceneName' } )
    .withCamera( { name: 'myCameraName' } )
    .withMesh( { name: 'myMeshName' } )
    .withRenderer( { name: 'myRendererName' } )
    .composify( {
      config: {
        start: true,
        scene: { main: 'mySceneName' },
        mesh: [ { name: 'myMeshName', parent: 'main' } ],
        light: [ { name: 'myLightName', parent: 'main' } ],
        camera: { main: 'myCameraName' },
        renderer: 'myRendererName'
      }
    } )
    .value();

  // use the onrender method to update a mesh, the callback take time in argument.
  THREEstarter.mesh.myMeshName.onrender( time => {

    THREEstarter.mesh.myMeshName.rotation.x += time;
    THREEstarter.mesh.myMeshName.rotation.y += time;

  } );

}, false );

html x javascript

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>d2k.js - example - hello world</title>
  </head>
  <body>
    <canvas id="myCanvasId" touch-action="none"></canvas>
    <script src="https://raw.githack.com/monsieurbadia/d2k.js/master/build/d2k.js"></script>
    <script src="https://threejs.org/build/three.js"></script>
    <script>
      window.addEventListener( 'DOMContentLoaded', function () {

        var THREEstarter = d2k
          .onstarter( { canvas: 'myCanvasId' } )
          .use( THREE )
          .withScene( { name: 'mySceneName' } )
          .withCamera( { name: 'myCameraName' } )
          .withMesh( { name: 'myMeshName' } )
          .withRenderer( { name: 'myRendererName' } )
          .composify( {
            config: {
              start: true,
              scene: { main: 'mySceneName' },
              mesh: [ { name: 'myMeshName', parent: 'main' } ],
              camera: { main: 'myCameraName' },
              renderer: 'myRendererName'
            }
          } )
          .value();

        // use the onrender method to update a mesh, the callback take time in argument.
        THREEstarter.mesh.myMeshName.onrender( time => {

          THREEstarter.mesh.myMeshName.rotation.x += time;
          THREEstarter.mesh.myMeshName.rotation.y += time;

        } );

      }, false );
    </script>
  </body>
</html>

Syntax

following this syntax bellow which allows you to chain methods to compose a scene step by step.

using glsl

create a 100% gpu scene through shader in GLSL

const GLSLstarter = d2k
  .onstarter( { canvas: 'myCanvasId', glsl: true } )
  .use( THREE ) //
  .withShader( /*  shader config */ )
  .value();

using babylon.js

create a scene from the primitives of BABYLON

const BABYLONstarter = d2k
  .onstarter( { canvas: 'myCanvasId' } )
  .use( BABYLON )
  .withEngine( /* engine config */)
  .withScene( /* scene config */)
  .withLight( /* light config */)
  .withMesh( /* mesh config */)
  .composify( /* composify config */ )
  .value();

using three.js

create a scene from the primitives of THREE

const THREEstarter = d2k
  .onstarter( { canvas: 'myCanvasId' } )
  .use( THREE )
  .withCamera( /* camera config */ )
  .withMesh( /* mesh config */ )
  .withRenderer( /* renderer config */ )
  .withLight( /* light config */ )
  .withLoader( /* loader config */ )
  .withScene( /* camera config */ )
  .composify( /* camera config */ )
  .value();

Configuration

a scene can be created from a JSON file and must respect the following format:

glsl config format - babylon.js config format - three.js config format

API

.onstarter( init )

initialize a scene from an init object pass in parameter. to create a scene .onstarter() has to be used first.

usage

GLSL x BABYLON x THREE

params

init { Object }: initialize a starter
returns { Object }: collection of methods.

example
const starter = d2k
  .onstarter( {
    canvas: 'myCanvasId', // or use an HTMLCanvasElement,
    glsl: false // optional
  } );

.use( RENDERING_ENGINE )

define the current RENDERING_ENGINE wich will be used to create primitives. .use() has to been calls just after the .onstarter() method.

usage

GLSL x BABYLON x THREE

params

RENDERING_ENGINE { Object }: the current engine (THREE | BABYLON)
returns { Object }: collection of methods.

example
const starter = d2k
  .onstarter( /* init */ )
  .use( BABYLON || THREE );

.withCamera( config )

create a camera from an config object pass in parameter.

usage

BABYLON x THREE

params

config { Object }: definition of the configuration of a camera.
returns { Object }: collection of methods.

example
const starter = d2k
  .onstarter( /* init */ )
  .use( BABYLON || THREE )
  .withCamera( {
    name: 'myCameraName',
    config: {
      args: [ 75, null, 0.1, 1000 ],
      position: [ 0, 0, 100 ],
      rotation: [ 0, 0, 0 ],
      scale: [ 1, 1, 1 ],
      type: 'perspective'
    }
  } );

.withEngine( config )

define an engine from a config object passed as a parameter.

usage

BABYLON

params

config { Object }: a engine config.
returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( BABYLON )
  .withEngine( { name: 'myEngineName' } );

.withMesh( config )

create a mesh from an config object pass in parameter.

usage

BABYLON x THREE

params

config { Object }: a mesh config. returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( BABYLON || THREE )
  .withMesh( {
    name: "myMeshName",
    config: {
      geometry: {
        args: [ 20, 20, 20 ],
        type: "box-buffer"
      },
      material: {
        args: { "transparent": true },
        type: "mesh-normal"
      },
      positions: [ -20, 0, 0 ],
    }
  } );

.withLight( config )

create a light from a config object pass in parameter.

usage

BABYLON x THREE

params

config { Object }: a light config. returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( BABYLON || THREE )
  .withLight( {
    name: "myLightName",
    config: {
      args: [ "0xf1f5bb" ],
      position: [ 0, 1, 30 ],
      type: "directional"
    }
  } );

.withLoader( config )

load a texture | object from a config object to pass in parameter.

usage

THREE

params

config { Object }: a loader config.
returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( THREE ) // you can also use BABYLON
  .withLoader( {
    name: "myLightName",
    config: {
      args: [ "0xf1f5bb" ],
      position: [ 0, 1, 30 ],
      type: "directional"
    }
  } );

.withRenderer( config )

create a renderer from a config object pass parameter.

usage

THREE

params

config { Object }: a renderer config.
returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( BABYLON || THREE )
  .withRenderer( {
    name: "myRendererName",
    config: {
      antialias: true,
      autoClear: true,
      pixelRatio: null,
      size: [],
      type: "webgl"
    }
  } );

.withScene( config )

compose a scene from a config object pass in parameter.

usage

BABYLON x THREE

params

config { Object }: a scene config.
returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( BABYLON || THREE )
  .withScene( { name: "mySceneName" } );

.withShader( config )

create shader from a config object pass in parameter.

usage

GLSL

params

config { Object }: a shader config
returns { Object }: collection of methods.

example
const starter = d2k.onstarter( /* init */ )
  .use( THREE )
  .withShader( {
    name: 'myShaderName',
    config : {
      vertexShader: `
        void main () {
          gl_Position = vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        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);
        }
      `
    }
  } );

.onrender( TARGET, SOURCE )

create a scene from a TARGET and a SOURCE pass in parameters. note: this method will get two different starter to merge them and display the two scenes through a single canvas. be careful, this part is still experimental.

usage

BABYLON x THREE 

params

TARGET { Object }: a THREE starter. SOURCE { Object }: a BABYLON starter. returns { Object }: a renderer.

example
// babylonjs only
BABYLONstarter.renderer.onrender( {
  engine: BABYLONstarter.engine.myEngineName
  scene: BABYLONstarter.scene.mySceneName
} );
// threejs only
THREEstarter.renderer.onrender( {
  renderer: THREEstarter.renderer,
  scene: THREEstarter.scene.main,
  camera: THREEstarter.camera.main
} );
// both together
d2k.onrender( {
  renderer: THREEstarter.renderer.current,
  scene: THREEstarter.scene.mySceneName,
  camera: THREEstarter.camera.current
}, {
  engine: BABYLONstarter.engine.current,
  scene: BABYLONstarter.scene.mySceneName
} );

.composify( config )

composition of the scene to be displayed. This method allows you to compose a scene step by step.

usage

BABYLON x THREE

params

config { Object }: a composify config.
returns { Object }: a renderer.

example
const starter = d2k.composify( {
  config: {
    start: true,
    scene: {
      main: 'mySceneName',
      others: []
    },
    mesh: [ { 'name': 'myMeshName', 'parent': 'main' } ],
    light: [ { 'name': 'myLightName', 'parent': 'main' } ],
    camera: {
      main: 'myCameraName',
      others: []
    },
    renderer: 'myRendererName'
  }
} );

.value()

returns a starter object that contains a collection of primitives. note: .value() can be called at any time during the creation step

usage

GLSL x BABYLON x THREE

params

no params
returns { Object }: a starter collection.

example
const starter = d2k
  .onstarter( /* init config */ )
  .use( BABYLON || THREE )
  .withCamera( /* camera config */ )
  .value();

starter

contains a collection of primitives you have created and some methods.

events

mesh light camera hold events which are called in specific contexts onrender onloader onresize.

onloader
// get textures
starter.mesh.myMeshName.onloader( textures => textures );
onrender
// update
starter.mesh.myMeshName.onrender( timer => {
  starter.mesh.myMeshName.rotation.x += time;
  starter.mesh.myMeshName.rotation.y += time;
} );
onresize
// resize
starter.mesh.myMeshName.onresize( size => {
  starter.mesh.myMeshName.material.uniforms.resolution.value.x += size.width;
  starter.mesh.myMeshName.rotation.uniforms.resolution.value.y += size.height;
} );

Tips

fetch scene from a JSON config file

// babylon
fetch( 'http://localhost:5007/api/scene/babylon' )
  .then( response => response.json() )
  .then( ( { scene } ) => {

    const starter = d2k
      .onstarter( { canvas: 'viewRendering' } )
      .use( BABYLON )
      .withEngine( scene.engine )
      .withScene( scene.scene )
      .withCamera( scene.camera )
      .withLight( scene.light )
      .withMesh( scene.mesh )
      .composify( scene.composify )
      .value();

    starter.mesh.myMeshName.onrender( time => {

      starter.mesh.myMeshName.rotation.x -= time;
      starter.mesh.myMeshName.rotation.y -= time;

    } );

  } );
// glsl
fetch( 'http://localhost:5007/api/scene/glsl' )
  .then( response => response.json() )
  .then( ( { scene } ) => {

    const starter = d2k
      .onstarter( scene.init )
      .use( THREE )
      .withShader( scene.shader )
      .value();

    starter.shader.myShaderName.onrender( time => time );

    starter.shader.myShaderName.onresize( size => {

      starter.shader.myShaderName.material.uniforms.resolution.value.x = size.width;
      starter.shader.myShaderName.material.uniforms.resolution.value.y = size.height;

    } );

  } );
// three
fetch( 'http://localhost:5007/api/scene/three' )
  .then( response => response.json() )
  .then( ( { scene } ) => {

    const starter = d2k
      .onstarter( { canvas: 'viewRendering' } )
      .use( THREE )
      .withCamera( scene.camera )
      .withRenderer( scene.renderer )
      .withMesh( scene.mesh )
      .withLight( scene.light )
      .withScene( scene.scene )
      .composify( scene.composify )
      .value();

    starter.mesh.myMeshName.onloader( textures => textures );

    starter.mesh.myMeshName.onrender( time => {

      starter.mesh.myMeshName.rotation.x += time;
      starter.mesh.myMeshName.rotation.y += time;

    } );

  } );
// async
const fetchStarterScene = async ( url ) => {

  const response = await fetch( url );
  const sceneConfig = await response.json();
  const data = d2k.onstarter( { canvas: 'viewRendering' } )
    .use( THREE )
    .onstarter( { canvas: 'viewRendering' } )
    .withCamera( scene.camera )
    .withRenderer( scene.renderer )
    .withMesh( scene.mesh )
    .withLight( scene.light )
    .withScene( scene.scene )
    .composify( scene.composify )
    .value();

  return data;

};

fetchStarterScene( 'https://mydomain.com/my/scene/config/endpoint' );

Primitives

primitive babylon.js three.js
audio
camera
font
geometry
group
light
loader
material
mesh
renderer
scene

Disclaimer

I am not a developer, I am a normal guy who carries programming in his heart and wants to contribute to open source and help the 3d community. for now, this is just an experimental version of an idea I had in mind. But my idea will evolve through this project so my design errors, over time, will disappear. changes will be coming for everyone's comfort, I hope. triforce!

References

License

Copyright ©️ 2020 monsieurbadia

Released under the MIT license

Support

⭐️ this repository if this project helped you!

Contributors

logo - @Mlle_Martinss
icons - @AdrienCoquet
code - @monsieurbadia