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

primitive builder based on three.js x babylon.js that will help you to created a scene in an intuitive and functional way.
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
JSONfile - support
GLSLxTHREExBABYLON - 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 d2kOR
yarn add d2kalternative
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
d2k.onstarter( init )initialize a
scenefrom aninitobject pass in parameter. to create a scene.onstarter()has to be used first.usage
GLSLxBABYLONxTHREEparams
init{ Object }: initialize astarterreturns{ 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_ENGINEwich will be used to create primitives..use()has to been calls just after the.onstarter()method.usage
GLSLxBABYLONxTHREEparams
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
camerafrom anconfigobject pass in parameter.usage
BABYLONxTHREEparams
config{ Object }: definition of the configuration of acamera.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
enginefrom aconfigobject passed as a parameter.usage
BABYLONparams
config{ Object }: aengineconfig.returns{ Object }: collection of methods.example
const starter = d2k.onstarter( /* init */ ) .use( BABYLON ) .withEngine( { name: 'myEngineName' } );
.withMesh( config )create a
meshfrom anconfigobject pass in parameter.usage
BABYLONxTHREEparams
config{ Object }: ameshconfig.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
lightfrom aconfigobject pass in parameter.usage
BABYLONxTHREEparams
config{ Object }: alightconfig.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|objectfrom aconfigobject to pass in parameter.usage
THREEparams
config{ Object }: aloaderconfig.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
rendererfrom aconfigobject pass parameter.usage
THREEparams
config{ Object }: arendererconfig.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
scenefrom aconfigobject pass in parameter.usage
BABYLONxTHREEparams
config{ Object }: asceneconfig.returns{ Object }: collection of methods.example
const starter = d2k.onstarter( /* init */ ) .use( BABYLON || THREE ) .withScene( { name: "mySceneName" } );
.withShader( config )create
shaderfrom aconfigobject pass in parameter.usage
GLSLparams
config{ Object }: ashaderconfigreturns{ 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); } ` } } );
d2k.onrender( TARGET, SOURCE )create a
scenefrom aTARGETand aSOURCEpass in parameters. note: this method will get two differentstarterto merge them and display the two scenes through a single canvas. be careful, this part is still experimental.usage
BABYLONxTHREEparams
TARGET{ Object }: aTHREEstarter.SOURCE{ Object }: aBABYLONstarter.returns{ Object }: arenderer.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
BABYLONxTHREEparams
config{ Object }: acomposifyconfig.returns{ Object }: arenderer.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
starterobject that contains a collection of primitives. note:.value()can be called at any time during the creation stepusage
GLSLxBABYLONxTHREEparams
no paramsreturns{ Object }: astartercollection.example
const starter = d2k .onstarter( /* init config */ ) .use( BABYLON || THREE ) .withCamera( /* camera config */ ) .value();
startercontains a collection of primitives you have created and some methods.
eventsmeshlightcamerahold events which are called in specific contextsonrenderonloaderonresize.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
