First commit

This commit is contained in:
2025-11-17 17:18:43 +01:00
parent 2286a3b782
commit bca5ef911b
905 changed files with 950521 additions and 2 deletions

164
README.md Normal file → Executable file
View File

@@ -1,3 +1,163 @@
# Kepler
A Modern pbr based Render Engine in WebGL.
Kepler is a open source deferred, pbr based render engine written in Javascript.
Current features are:
# Load models:
```javascript
import keplerEngine from './engine/kepler.js';
import sampler2D from './engine/sampler2D.js';
import viewport from './engine/viewport.js';
// Create raprtor engine instance
kepler = new keplerEngine();
// Create viewport to dom element width id keplerEngine
var ViewPort = new viewport("keplerEngine");
// Load 3d model
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
// Add viewport
kepler.addViewport( ViewPort );
// Start application
kepler.application();
```
# Create primitives (Entity's, Materials, textures, samplers):
```javascript
import keplerEngine from './engine/kepler.js';
import entity from './engine/entity.js';
import material from './engine/material.js';
import sampler2D from './engine/sampler2D.js';
import mesh from './engine/mesh.js';
import viewport from './engine/viewport.js';
kepler = new keplerEngine();
// Viewport
var ViewPort = new viewport("keplerEngine");
// Material
var groundMaterial = new material();
// Create Normal Texture and Sampler
var normalTexture = kepler.resources.getTexture("floorTiles_normal.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
// Create Diffuse Texture and Sampler
var diffuseTexture = kepler.resources.getTexture("floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
// Add Samplers to Material
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
// Properties
groundMaterial.diffuseColor = [179.0 / 256.0, 199.0 / 256.0, 217.0 / 256.0];
groundMaterial.alpha = 1.0;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.3;
groundMaterial.metalic = 0.1;
groundMaterial.uvMultiplier = 6.0;
// Create cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
cubeMesh.addMaterial(groundMaterial);
// Create cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "Cube";
cubeEntity.transform.position = [0, 10, 0];
cubeEntity.transform.update();
// Add cube entity to scene
ViewPort.scene.addEntity( cubeEntity );
// Start application
kepler.application();
```
# Renderpass:
```javascript
import defaultRenderPass from '../defaultRenderPass.js';
import sampler2D from '../sampler2D.js';
import shader from '../shader.js';
class tonemap extends defaultRenderPass {
prepare() {
var randomTexure = kepler.resources.getTexture("random.png");
var randomSampler = new sampler2D();
randomSampler.addTexture(randomTexure);
this.shader = new shader();
this.shader.createFromFile("shaders/tonemap.shader");
// set uniforms like this
this.shader.setUniform("exposure", 1.1 );
this.shader.setUniform("exampleVector2", [1,1] );
this.shader.setUniform("exampleVector3", [1,1,1] );
this.shader.setUniform("randomSampler", randomSampler );
}
}
export {tonemap as default};
```
In rendersytem.js in the method createRenderPasses add:
```javascript
import tonemap from './renderPasses/tonemap.js';
var tonemapPass = new tonemap();
this.deferredRenderPipeline.addRenderpass( tonemapPass, "uber" );
//tonemapPass.renderToViewport = true;
tonemapPass.shader.setUniform("colorSampler", uberPass.framebuffer.getSampler() );
```
## tonemap.shader
```glsl
attribute vec3 position;
attribute vec2 uv;
uniform mat4 viewProjection;
varying vec2 v_textureCoord;
void main(void) {
v_textureCoord = uv;
gl_Position = viewProjection * vec4(position, 1.0);
}
// #keplerEngine - Split
precision highp float;
uniform sampler2D colorSampler;
varying vec2 v_textureCoord;
void main() {
vec3 color = texture2D( colorSampler, v_textureCoord ).rgb;
gl_FragColor = vec4( tonemap(color), 1.0 );
}
```

BIN
about/raptorPBR.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
about/raptorStructure.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

199
demos/metalic.htm Executable file
View File

@@ -0,0 +1,199 @@
<html>
<head>
<title>Kepler</title>
<script src="../media/libs/jquery/jquery.js"></script>
</head>
<script>
var kepler;
var gl;
</script>
<script type="module">
import keplerEngine from '../engine/kepler.js';
import entity from '../engine/entity.js';
import material from '../engine/material.js';
import sampler2D from '../engine/sampler2D.js';
import samplerCube from '../engine/samplerCube.js';
import mesh from '../engine/mesh.js';
import viewport from '../engine/viewport.js';
import {matrix4} from '../engine/math.js';
import template from '../engine/renderPasses/template.js';
import scene from '../engine/scene.js';
kepler = new keplerEngine();
var ViewPort = new viewport("keplerEngine");
ViewPort.scene = new scene();
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 20.1, -20.01];
light.type = "skyLight";
//light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
//light.showFrustum = true;
light.degrees = 60;
ViewPort.scene.addEntity( light );
//ViewPort.system.setRenderMode("deferred");
ViewPort.system.reflectionSampler = new samplerCube();
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
var materialNames = ["plasticpattern1", "scuffed-plastic", "rustediron-streaks", "octostone", "paint-peeling", "wornpaintedcement", "pockedconcrete1", "hardwood-brown-planks", "darktiles1"];
for(var c = 0; c < 6; c++) {
var materialName = '';
var x = (270 * c);
createMeshInstance( materialName, [x-600, 0, 0], c, ViewPort);
}
function createMeshInstance(textureName, position, index, currentViewport ) {
console.log(textureName);
var diffuseTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-albedo.png" );
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var normalTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-normal.png" );
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var roughnessTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-roughness"+".png" );
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
var instanceMaterial = new material();
//instanceMaterial.addTexture(diffuseSampler);
//instanceMaterial.addNormal(normalSampler);
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
instanceMaterial.diffuseColor = [130/256,170/256,211/256];
instanceMaterial.metallic = index / 6;
instanceMaterial.alpha = 1;
instanceMaterial.create();
instanceMaterial.roughness = .2;
console.log(currentViewport.scene);
//copyMesh
var oldEntity = ViewPort.scene.getEntityByName("GrayInlay");
var oldMesh = oldEntity.mesh;
var meshCopy = new mesh();
// old way
//meshCopy.createMeshFromArrays( oldMesh.indices,
// oldMesh.vertices,
// oldMesh.normals,
// oldMesh.textureCoordinates,
// oldMesh.tangents,
// oldMesh.binormals );
meshCopy.copyMesh( oldMesh );
meshCopy.addMaterial(instanceMaterial);
var cloneEntity = new entity();
cloneEntity.parent = ViewPort.scene.entitys[5].parent;
cloneEntity.addMesh( meshCopy );
cloneEntity.name = textureName;
cloneEntity.transform.position = position;
cloneEntity.transform.update();
currentViewport.scene.addEntity( cloneEntity );
}
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.alpha = 0;
kepler.addViewport( ViewPort );
// Material
var groundMaterial = new material();
// Samplers
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
//groundMaterial.addRoughness(normalSampler);
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
var skyMaterial = new material();
skyMaterial.roughness = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 6;
skyMaterial.shadingModelID = 100.0;
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.diffuseColor = [1,1,1];
kepler.application();
</script>
<body style="margin: 0;">
<img src="../media/textures/logo.png" style="position: absolute;left:0; top:10px;" >
<canvas id="keplerEngine" style="width: 100%; height: 100%;"></canvas>
</body>
</html>

175
demos/new.htm Executable file
View File

@@ -0,0 +1,175 @@
<html>
<head>
<title>Kepler</title>
</head>
<link rel="stylesheet" type="text/css" href="../loading-bar.css"/>
<script type="text/javascript" src="../loading-bar.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.js"></script>
<link rel="stylesheet" href="../style.css" type="text/css">
<script type="module">
import keplerEngine from '../engine/kepler.js';
import entity from '../engine/entity.js';
import material from '../engine/material.js';
import sampler2D from '../engine/sampler2D.js';
import {matrix4} from '../engine/math.js';
var kepler = new keplerEngine();
kepler.bar = new ldBar(".preloader");
kepler.initialize = function() {
this.resources.addTexture("media/textures/white.png", 'white');
this.resources.addTexture("media/textures/rotrandom.png", 'random');
this.resources.addTexture("media/textures/0_floorTiles_diff.png", 'floorTiles_diff');
this.resources.addTexture("media/textures/0_floorTiles_ddn.png", 'floorTiles_normal');
this.resources.addTexture("media/textures/cubemaps-1024/positive_x.png", 'positive_x');
this.resources.addTexture("media/textures/cubemaps-1024/positive_y.png", 'positive_y');
this.resources.addTexture("media/textures/cubemaps-1024/positive_z.png", 'positive_z');
this.resources.addTexture("media/textures/cubemaps-1024/negative_x.png", 'negative_x');
this.resources.addTexture("media/textures/cubemaps-1024/negative_y.png", 'negative_y');
this.resources.addTexture("media/textures/cubemaps-1024/negative_z.png", 'negative_z');
//this.assimpLoader.load("room.json");
//this.assimpLoader.load("laren2.json");
}
kepler.callback = function() {
var engine = this;
var light = new entity( engine );
light.type = "PointLight";
light.name = "PhotometricLight003";
light.transform.local = matrix4.identity();
light.transform.world = matrix4.setTranslation( light.transform.local, [100.0702958800057496, 120.042, 4100] );
light.mesh = false;
light.attenuation = 1.5;
light.SourceRadius = 0;
light.SourceLength = 0;
engine.system.scene.rootEntity.addChild(light);
engine.system.scene.addEntity( light );
console.log(engine);
var currentMaterial = new material(engine);
var normalTexture = engine.resources.getTexture("floorTiles_normal");
var normalSampler = new sampler2D(engine);
normalSampler.addTexture(normalTexture);
currentMaterial.addNormal(normalSampler);
var diffuseTexture = engine.resources.getTexture("floorTiles_diff");
var diffuseSampler = new sampler2D(engine);
diffuseSampler.addTexture(diffuseTexture);
currentMaterial.addTexture( diffuseSampler );
currentMaterial.roughness = .0;
currentMaterial.shadingModelID = 256;
//material.diffuseColor = [88,175,255];
currentMaterial.alpha = 1;
var currentMesh = engine.primitives.createCube(10);
//var mesh = this.primitives.createSphere(2.6, 200, 200)
currentMesh.addMaterial(currentMaterial);
var box = new entity( engine );
box.addMesh(currentMesh);
box.name = "new box";
box.alpha = 0;
box.transform.position = [0, -10, 0];
box.transform.update();
box.mesh.boundingBox.fitBoxToPoints_(box.mesh.vertexPositionBuffer.data, box.transform.world);
engine.system.scene.addEntity( box );
engine.system.scene.rootEntity.addChild(box);
var skyMaterial = new material(engine);
var diffuseTexture = engine.resources.getTexture("white");
var diffuseSampler = new sampler2D( engine );
diffuseSampler.addTexture(diffuseTexture);
skyMaterial.addTexture(diffuseSampler);
skyMaterial.roughness = .0;
skyMaterial.shadingModelID = 100.0;
skyMaterial.diffuseColor = [88,175,255];
skyMaterial.alpha = 1;
skyMaterial.create();
var sphere = engine.primitives.createSphere(712.6, 200, 200)
sphere.addMaterial(skyMaterial);
var sky = new entity( engine );
sky.addMesh(sphere);
sky.name = "sky sphere";
sky.transform.position = [0, 20, 0];
sky.transform.update();
//engine.system.scene.addEntity( sky );
//engine.system.scene.rootEntity.addChild( sky );
}
kepler.application();
</script>
<body style="margin: 0;">
<div class="preloader_holder">
<div class="preloader"
data-preset="fan"
class="ldBar label-center"
style="width:100%;height:100%;margin:auto"
>
</div>
<div class="preloader_text">
</div>
</div>
<img src="media/textures/logo.png" style="position: absolute;left:0; top:10px;" >
<canvas id="keplerEngine" style="width: 100%; height: 100%;"></canvas>
</body>
</html>

300
demos/pointLight.htm Executable file
View File

@@ -0,0 +1,300 @@
<html>
<head>
<title>Kepler</title>
<script src="../media/libs/jquery/jquery.js"></script>
</head>
<script>
var kepler;
var gl;
var gl2;
</script>
<script type="module">
import keplerEngine from '../engine/kepler.js';
import entity from '../engine/entity.js';
import material from '../engine/material.js';
import sampler2D from '../engine/sampler2D.js';
import samplerCube from '../engine/samplerCube.js';
import mesh from '../engine/mesh.js';
import viewport from '../engine/viewport.js';
import {matrix4} from '../engine/math.js';
import template from '../engine/renderPasses/template.js';
import sceneNode from '../engine/scene.js';
kepler = new keplerEngine();
var ViewPort = new viewport("keplerEngine");
kepler.assimpLoader.load( "lamp.json", ViewPort.scene );
//kepler.assimpLoader.load( "demo.json", ViewPort.scene );
//ViewPort.system.setRenderMode("deferred");
ViewPort.system.reflectionSampler = new samplerCube();
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
var light = new entity( );
light.name = "pointLight";
light.transform.position = [0, 4.1, 0.01];
//light.transform.position = [0, 15.1, 0.01];
light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
light.showFrustum = true;
//light.degrees = 30;
light.degrees = 130;
light.transform.update();
ViewPort.scene.addEntity( light );
/*
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 3.4, 12.01];
light.type = "pointLight";
light.showFrustum = true;
light.transform.update();
ViewPort.scene.addEntity( light );
*/
var found = ViewPort.scene.getLights();
console.log('found', found );
var materialNames = ["plasticpattern1", "scuffed-plastic", "rustediron-streaks", "octostone", "paint-peeling", "wornpaintedcement", "pockedconcrete1", "hardwood-brown-planks", "darktiles1"];
for(var c = 0; c < materialNames.length; c++) {
var materialName = materialNames[c];
var x = (3 * c) % 12;
var y = Math.floor(c / 3) * 3;
//if(c != 4)
//createMeshInstance( materialName, [x-3, -2.5, y-3],5, ViewPort);
}
function createMeshInstance(textureName, position, index, currentViewport ) {
console.log(textureName);
var diffuseTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-albedo.png" );
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var normalTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-normal.png" );
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var roughnessTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-roughness"+".png" );
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
var instanceMaterial = new material();
instanceMaterial.addTexture(diffuseSampler);
instanceMaterial.addNormal(normalSampler);
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
instanceMaterial.alpha = 1;
instanceMaterial.create();
instanceMaterial.roughness = .2;
console.log(currentViewport.scene);
//copyMesh
var oldEntity = ViewPort.scene.getEntityByName("Almerich_Coco_S_mat(1)");
var oldMesh = oldEntity.mesh;
var meshCopy = new mesh();
// old way
//meshCopy.createMeshFromArrays( oldMesh.indices,
// oldMesh.vertices,
// oldMesh.normals,
// oldMesh.textureCoordinates,
// oldMesh.tangents,
// oldMesh.binormals );
meshCopy.copyMesh( oldMesh );
meshCopy.addMaterial(instanceMaterial);
var cloneEntity = new entity();
cloneEntity.parent = ViewPort.scene.rootEntity;
cloneEntity.addMesh( meshCopy );
cloneEntity.name = textureName;
cloneEntity.transform.position = position;
cloneEntity.transform.scale = [0.3, 0.3, 0.3];
cloneEntity.transform.rotateY(90);
cloneEntity.transform.update();
currentViewport.scene.addEntity( cloneEntity );
}
var oldEntity = ViewPort.scene.getEntityByName("GrayInlay");
//ViewPort.scene.getEntityByName("GrayInlay").mesh.material.diffuseColor = [1,1,1];
kepler.addViewport( ViewPort );
/*
// Material
var groundMaterial = new material();
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
// Cube mesh
//var cubeMesh = ViewPort.primitives.createCube(10);
//radius, subdivisions, maxTexCoord
var frustumMesh = ViewPort.linePrimitives.createLineRingVertices(10, 10, 10);
var shadowCamera = ViewPort.system.createShadowCam( [0, 10, 1], [0, -1, 0], [0, 1, 0] )
var frustumMesh = ViewPort.linePrimitives.drawFrustum( shadowCamera.projection, shadowCamera.view );
//var depthpass = ViewPort.system.deferredRenderPipeline.getRenderpass("depth");
//depthpass.shadowCameras.push( shadowCamera );
//console.log("wireframe cube", cubeMesh);
console.log("wireframe frustum", frustumMesh);
frustumMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( frustumMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, 0, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
*/
// Samplers
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var skyMaterial = new material();
skyMaterial.roughness = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 6;
skyMaterial.addNormal(normalSampler);
skyMaterial.addTexture(diffuseSampler);
//skyMaterial.shadingModelID = 100.0;
var sphere = ViewPort.primitives.createSphere(2, 200, 200)
sphere.addMaterial(skyMaterial);
var box = new entity( );
box.addMesh(sphere);
box.name = "sky sphere";
box.transform.position = [1100, 0, 0];
box.transform.update();
ViewPort.scene.addEntity( box );
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
var diffuseTexture = kepler.resources.getTexture("lamp/wood_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var cubeMaterial = new material();
cubeMaterial.roughness = 0.4;
cubeMaterial.diffuseColor = [179/256,199/256,217/256];
cubeMaterial.alpha = 1;
cubeMaterial.uvMultiplier = 4;
//cubeMaterial.shadingModelID = 100.0;
//cubeMaterial.addNormal(normalSampler);
cubeMaterial.addTexture(diffuseSampler);
cubeMesh.addMaterial(cubeMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
var skyMaterial = new material();
skyMaterial.roughness = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 1;
skyMaterial.shadingModelID = 100.0;
var sphere = ViewPort.primitives.createSphere(100, 200, 200)
sphere.addMaterial(skyMaterial);
var box = new entity( );
box.addMesh(sphere);
box.name = "sky sphere";
box.transform.position = [0, 0, 0];
box.transform.update();
//ViewPort.scene.addEntity( box );
kepler.application();
</script>
<body style="margin: 0; padding: 0;">
<img src="../media/textures/logo.png" style="position: absolute;left:0; top:10px;" >
<canvas id="keplerEngine" style="width: 100%; height: 100%; float:left;"></canvas>
</body>
</html>

200
demos/reflectance.htm Executable file
View File

@@ -0,0 +1,200 @@
<html>
<head>
<title>Kepler</title>
<script src="../media/libs/jquery/jquery.js"></script>
</head>
<script>
var kepler;
var gl;
</script>
<script type="module">
import keplerEngine from '../engine/kepler.js';
import entity from '../engine/entity.js';
import material from '../engine/material.js';
import sampler2D from '../engine/sampler2D.js';
import samplerCube from '../engine/samplerCube.js';
import mesh from '../engine/mesh.js';
import viewport from '../engine/viewport.js';
import {matrix4} from '../engine/math.js';
import template from '../engine/renderPasses/template.js';
import scene from '../engine/scene.js';
kepler = new keplerEngine();
var ViewPort = new viewport("keplerEngine");
ViewPort.scene = new scene();
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 20.1, -20.01];
light.type = "skyLight";
//light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
//light.showFrustum = true;
light.degrees = 60;
ViewPort.scene.addEntity( light );
//ViewPort.system.setRenderMode("deferred");
ViewPort.system.reflectionSampler = new samplerCube();
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
var materialNames = ["plasticpattern1", "scuffed-plastic", "rustediron-streaks", "octostone", "paint-peeling", "wornpaintedcement", "pockedconcrete1", "hardwood-brown-planks", "darktiles1"];
for(var c = 0; c < 6; c++) {
var materialName = '';
var x = (270 * c);
createMeshInstance( materialName, [x-600, 0, 0], c, ViewPort);
}
function createMeshInstance(textureName, position, index, currentViewport ) {
console.log(textureName);
var diffuseTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-albedo.png" );
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var normalTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-normal.png" );
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var roughnessTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-roughness"+".png" );
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
var instanceMaterial = new material();
//instanceMaterial.addTexture(diffuseSampler);
//instanceMaterial.addNormal(normalSampler);
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
instanceMaterial.diffuseColor = [130/256,170/256,211/256];
instanceMaterial.metallic = index / 6;
instanceMaterial.alpha = 1;
instanceMaterial.create();
instanceMaterial.roughness = .2;
console.log(currentViewport.scene);
//copyMesh
var oldEntity = ViewPort.scene.getEntityByName("GrayInlay");
var oldMesh = oldEntity.mesh;
var meshCopy = new mesh();
// old way
//meshCopy.createMeshFromArrays( oldMesh.indices,
// oldMesh.vertices,
// oldMesh.normals,
// oldMesh.textureCoordinates,
// oldMesh.tangents,
// oldMesh.binormals );
meshCopy.copyMesh( oldMesh );
meshCopy.addMaterial(instanceMaterial);
var cloneEntity = new entity();
cloneEntity.parent = ViewPort.scene.entitys[5].parent;
cloneEntity.addMesh( meshCopy );
cloneEntity.name = textureName;
cloneEntity.transform.position = position;
cloneEntity.transform.update();
currentViewport.scene.addEntity( cloneEntity );
}
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.alpha = 0;
kepler.addViewport( ViewPort );
// Material
var groundMaterial = new material();
// Samplers
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
//groundMaterial.addRoughness(normalSampler);
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
var skyMaterial = new material();
skyMaterial.reflectance = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 6;
skyMaterial.shadingModelID = 100.0;
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.diffuseColor = [1,1,1];
kepler.application();
</script>
<body style="margin: 0;">
<img src="../media/textures/logo.png" style="position: absolute;left:0; top:10px;" >
<canvas id="keplerEngine" style="width: 100%; height: 100%;"></canvas>
</body>
</html>

199
demos/rough.htm Executable file
View File

@@ -0,0 +1,199 @@
<html>
<head>
<title>Kepler</title>
<script src="../media/libs/jquery/jquery.js"></script>
</head>
<script>
var kepler;
var gl;
</script>
<script type="module">
import keplerEngine from '../engine/kepler.js';
import entity from '../engine/entity.js';
import material from '../engine/material.js';
import sampler2D from '../engine/sampler2D.js';
import samplerCube from '../engine/samplerCube.js';
import mesh from '../engine/mesh.js';
import viewport from '../engine/viewport.js';
import {matrix4} from '../engine/math.js';
import template from '../engine/renderPasses/template.js';
import scene from '../engine/scene.js';
kepler = new keplerEngine();
var ViewPort = new viewport("keplerEngine");
ViewPort.scene = new scene();
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 20.1, -20.01];
light.type = "skyLight";
//light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
//light.showFrustum = true;
light.degrees = 70;
ViewPort.scene.addEntity( light );
//ViewPort.system.setRenderMode("deferred");
ViewPort.system.reflectionSampler = new samplerCube();
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
var materialNames = ["plasticpattern1", "scuffed-plastic", "rustediron-streaks", "octostone", "paint-peeling", "wornpaintedcement", "pockedconcrete1", "hardwood-brown-planks", "darktiles1"];
for(var c = 0; c < 6; c++) {
var materialName = '';
var x = (270 * c);
createMeshInstance( materialName, [x-600, 0, 0], c, ViewPort);
}
function createMeshInstance(textureName, position, index, currentViewport ) {
console.log(textureName);
var diffuseTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-albedo.png" );
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var normalTexture = kepler.resources.getTexture( "pbr-1024/"+textureName+"/"+textureName+"-normal.png" );
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var roughnessTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-roughness"+".png" );
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
var instanceMaterial = new material();
//instanceMaterial.addTexture(diffuseSampler);
//instanceMaterial.addNormal(normalSampler);
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
instanceMaterial.diffuseColor = [130/256,170/256,211/256];
instanceMaterial.roughness = index / 6;
instanceMaterial.alpha = 1;
instanceMaterial.create();
console.log(currentViewport.scene);
//copyMesh
var oldEntity = ViewPort.scene.getEntityByName("GrayInlay");
var oldMesh = oldEntity.mesh;
var meshCopy = new mesh();
// old way
//meshCopy.createMeshFromArrays( oldMesh.indices,
// oldMesh.vertices,
// oldMesh.normals,
// oldMesh.textureCoordinates,
// oldMesh.tangents,
// oldMesh.binormals );
meshCopy.copyMesh( oldMesh );
meshCopy.addMaterial(instanceMaterial);
var cloneEntity = new entity();
cloneEntity.parent = ViewPort.scene.entitys[5].parent;
cloneEntity.addMesh( meshCopy );
cloneEntity.name = textureName;
cloneEntity.transform.position = position;
cloneEntity.transform.update();
currentViewport.scene.addEntity( cloneEntity );
}
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.alpha = 0;
kepler.addViewport( ViewPort );
// Material
var groundMaterial = new material();
// Samplers
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
//groundMaterial.addRoughness(normalSampler);
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
var skyMaterial = new material();
skyMaterial.reflectance = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 6;
skyMaterial.shadingModelID = 100.0;
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.diffuseColor = [1,1,1];
kepler.application();
</script>
<body style="margin: 0;">
<img src="../media/textures/logo.png" style="position: absolute;left:0; top:10px;" >
<canvas id="keplerEngine" style="width: 100%; height: 100%;"></canvas>
</body>
</html>

795
engine/assimp.js Executable file
View File

@@ -0,0 +1,795 @@
/*
* Copyright 2019, kaj dijkstra,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import scene from './scene.js';
import shader from './shader.js';
import mesh from './mesh.js';
import material from './material.js';
import sampler2D from './sampler2D.js';
import entity from './entity.js';
import {matrix3, matrix4} from './math.js';
import boundingBox from './boundingBox.js';
/**
* Player object
**/
class assimp
{
constructor() {
this.baseUrl = "http://localhost:4000";
this.modelPath = '/media/models/';
this.meshes = [];
this.scene = new scene();
this.shader = new shader();
this.filesToLoad = [];
this.name = "new";
this.models = [];
this.animations;
this.skeleton;
this.lightNames = ["PhotometricLight", "FPoint"];
this.shadingModelIDS = [];
this.bindMaterial("$ColladaAutoName$_108", 10.0);
this.bindMaterial("Box002", 1.0);
this.json;
this.materialCache;
}
stringStartsWith( string, compare ) {
if (string.substring(0, compare.length) == compare)
return true;
else
return false;
}
nameIsLight( name ) {
for(var c = 0; c<this.lightNames.length; c++) {
if(this.stringStartsWith(name, this.lightNames[c])) {
return true;
}
}
return false;
}
addModel( json ) {
this.models.push(json);
}
bindMaterial( entityName, shadingModelID ) {
this.shadingModelIDS.push({name:entityName, id:shadingModelID});
}
getShadingIdByEntityName( entityName ) {
for(var c = 0; c<this.shadingModelIDS.length; c++) {
console.log(this.shadingModelIDS[c].name, entityName);
if(this.shadingModelIDS[c].name == entityName)
return this.shadingModelIDS[c].id;
}
return 0;
}
serializeUrl( url, part_two ) {
if(url) {
// Remove backslash
var urlParts = url.split("\\");
url = urlParts[urlParts.length-1];
// Force extension to png
urlParts = url.split(".");
urlParts[urlParts.length-1] = "png";
url = urlParts.join(".");
// type
urlParts = url.split("_");
if(urlParts.length > 1) {
urlParts[urlParts.length-1] = part_two + ".png";
} else {
}
url = urlParts.join("_");
//remove slash
urlParts = url.split("/");
return urlParts[ urlParts.length - 1 ];
} else {
return false;
}
}
/**
* update object
**/
load( jsonFilename, scene ) {
console.log("load file", this.modelPath + jsonFilename);
var filenameParts = jsonFilename.split(".");
this.name = filenameParts[0];
this.scene = scene;
var data = this.loadTextFileSynchronous( this.baseUrl + this.modelPath + jsonFilename );
this.processFiles(data);
console.log("filesToLoad", jsonFilename, this);
}
get_filesize(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("HEAD", url, true); // Notice "HEAD" instead of "GET",
// to get only the header
xhr.onreadystatechange = function(ev) {
if (this.readyState == this.DONE) {
console.log('evevev', ev.target.responseURL);
var url = ev.target.responseURL;
var size = parseInt(ev.target.getResponseHeader("Content-Length"));
//kepler.loader.add(url, size );
}
};
xhr.engine = kepler;
xhr.send();
}
/**
* load url
* @param {string} url
*/
loadTextFileSynchronous(url, callback) {
/*
this.get_filesize( url );
var fileContent = kepler.resources.getFile(url)
if(fileContent) {
return fileContent.data;
}
*/
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
if (request.overrideMimeType) {
request.overrideMimeType('text/plain');
}
} else if (window.ActiveXObject) {
request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
} else {
throw 'XMLHttpRequest is disabled';
}
request.onprogress = callback = function (evt) {
console.log("onupdate", evt);
//kepler.loader.update( evt.target.responseURL, evt.loaded, evt.total );
};
request.onload = function (evt) {
if (request.readyState === request.DONE) {
if (request.status === 200) {
//console.log(request.response);
//console.log(request.responseText);
this.assimp.filesToLoad.push({data: request.responseText, filename: request.responseURL });
//'this.assimp.filesToLoad.push(evt.responseText);
}
}
};
request.onreadystatechange = function (evt) {
console.log("finish", evt.target.readyState);
if(evt.target.readyState == 4) {
}
};
request.open('GET', url, false);
request.engine = this.engine;
request.assimp = this;
request.send();
var data = request.responseText;
return data;
}
processFiles(json)
{
//var json = this.filesToLoad[0];
this.json = JSON.parse( json );
this.json.parsedMeshes = new Array();
var materials = this.json.materials;
var meshes = this.json.meshes;
var rootnode = this.json.rootnode;
var children = rootnode.children;
this.animations = this.json.animations;
var materialCache = new Array();
// get materials
for(var c = 0; c < materials.length; c++) {
var Material = materials[c];
var properties = Material.properties;
var name = this.getPropertyByName(properties, '?mat.name', 0).value;
var diffuseAdress = this.serializeUrl( this.getPropertyByName(properties, '$tex.file', 1).value, "diff");
var normalAdress = this.serializeUrl( this.getPropertyByName(properties, '$tex.file', 1).value, "ddn");
var roughAdress = this.serializeUrl( this.getPropertyByName(properties, '$tex.file', 1).value, "rough");
var depthAdress = this.serializeUrl( this.getPropertyByName(properties, '$tex.file', 1).value, "depth");
var diffuseColor = this.getPropertyByName(properties, "$clr.diffuse", 0).value;
var opacity = this.getPropertyByName(properties, "$mat.opacity", 0).value;
var roughness = this.getPropertyByName(properties, "$mat.shinpercent", 0).value;
console.log('diffuseAdress', diffuseAdress);
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var currentMaterial = new material( );
//if(diffuseAdress)
//currentMaterial.addTexture(diffuseSampler);
//currentMaterial.addNormal(normalSampler);
if(!diffuseColor) {
currentMaterial.diffuseColor = [1,1,1];
//currentMaterial.diffuseColor = [Math.random(), Math.random(), Math.random()];
} else {
currentMaterial.diffuseColor = diffuseColor;
}
//currentMaterial.diffuseColor = [Math.random(), Math.random(), Math.random()];
if(kepler.resources.getTexture( this.name + "/" + diffuseAdress )){
//currentMaterial.addTexture(diffuseSampler);
//currentMaterial.addNormal(normalSampler);
} else {
}
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
currentMaterial.roughness = 0.0;
currentMaterial.alpha = 1;
//currentMaterial.create();
currentMaterial.roughness = .01;
currentMaterial.reflectance = .01;
materialCache[c] = currentMaterial;
}
// get meshes
for(var mesh_id = 0; mesh_id < meshes.length; mesh_id++) {
this.json.parsedMeshes[mesh_id] = [];
var meshInfo = meshes[mesh_id];
this.parseMesh( meshInfo, mesh_id );
}
this.addModel( this.json );
//kepler.resources.loadNextTexture();
this.buildModels(materialCache);
}
parseMesh( meshInfo, mesh_id ) {
/*
if(meshInfo.faces.length > 60000) {
var cutFaces = meshInfo.faces.splice(60000, meshInfo.faces.length);
var newMesh = JSON.parse(JSON.stringify( meshInfo ));
newMesh.faces = cutFaces;
newMesh.name = "sliced mesh";
this.parseMesh( newMesh, mesh_id );
}
*/
//facesOriginal =
//console.log("meshInfo.faces", meshInfo.faces.length);
//flatten
var indices = [];
var vertices = [];
var normals = [];
for(var i = 0; i<meshInfo.faces.length; i++) {
var face = meshInfo.faces[i];
indices[i * 3] = face[0];
indices[i * 3 + 1] = face[1];
indices[i * 3 + 2] = face[2];
}
var min = getMin(indices);
var max = getMax(indices);
var minVert = min;
var maxVert = ((max ) ) - minVert; // number of items (x,y,z) = 3, 3 x 3 = face
var minUV = min;
var maxUV = ((max)) - minUV;
for(var i = 0; i<indices.length; i++) {
// indices[i] = indices[i] ;// - min;
}
//console.log(min, max);
//console.log("meshInfo.vertices", meshInfo.vertices.length);
function getMax(arr) {
let len = arr.length;
let max = -Infinity;
while (len--) {
max = arr[len] > max ? arr[len] : max;
}
return max;
}
function getMin(arr) {
let len = arr.length;
let min = Infinity;
while (len--) {
min = arr[len] < min ? arr[len] : min;
}
return min;
}
//console.log(getMax(indices));
var currentMesh = new mesh();
if( meshInfo.texturecoords ){
console.log( meshInfo, "Meshinfo" );
var sliced_vertices = meshInfo.vertices;//.splice(minVert, maxVert);//.slice(min, max);
var sliced_normals = meshInfo.normals;//splice(minVert, maxVert);
var sliced_tangents = meshInfo.tangents;
var sliced_uv = meshInfo.texturecoords[0];//.slice(minUV, maxUV);
currentMesh.createMeshFromArrays( indices, sliced_vertices, sliced_normals, sliced_uv, sliced_tangents, meshInfo.bitangents );
currentMesh.material = meshInfo.materialindex;
}
this.json.parsedMeshes[mesh_id].push(currentMesh);
}
parseNode( currentAssimpJson, assimpNode, parentEntity, scene, materialCache ) {
var currentEntity = new entity(this.engine);
currentEntity.name = assimpNode.name;
currentEntity.transform.world = matrix4.fromArray(assimpNode.transformation);
currentEntity.transform.local = matrix4.fromArray(assimpNode.transformation);
if(this.nameIsLight(currentEntity.name)) {
currentEntity.type = "PointLight";
scene.addEntity( currentEntity );
} else {
if(assimpNode.meshes) {
currentEntity.type = "Actor";
} else {
currentEntity.type = "transform";
scene.addEntity( currentEntity );
}
}
if(assimpNode.meshes) {
var meshID = assimpNode.meshes[0];
var meshes = currentAssimpJson.parsedMeshes[meshID];
for(var c = 0;c<meshes.length;c++) {
var currentMesh = meshes[c];
var currentEntity = new entity(this.engine);
currentEntity.name = assimpNode.name;
currentEntity.transform.world = matrix4.fromArray(assimpNode.transformation);
currentEntity.transform.local = matrix4.fromArray(assimpNode.transformation);
currentEntity.type = "Actor";
//if(global_material_id < 30) {
//var mesh = currentAssimpJson.parsedMeshes[meshID];
var transformation = assimpNode.transformation;
//var materialInfo = mesh.material;//new material();
var materialID = currentMesh.material;
var Material = materialCache[materialID];
if(Material) {
currentMesh.addMaterial(Material);
currentEntity.addMesh(currentMesh);
//currentEntity.transform.world = matrix4.mul( matrix4.fromArray(transformation), matrix4.fromArray( rootnode.transformation ) );
currentEntity.transform.local = matrix4.fromArray(transformation);
currentEntity.transform.position = matrix4.getWorldPosition(currentEntity.transform.local);
currentEntity.transform.scale = matrix3.getScale( currentEntity.transform.local );
currentEntity.transform.rotation = matrix3.getRotation( currentEntity.transform.local );
currentEntity.transform.world = currentEntity.transform.local;//matrix4.mul( parentEntity.transform.world, entity.transform.local );
//entity.objectTransform = matrix4.mul( matrix4.fromArray(transformation), matrix4.fromArray( rootnode.transformation ) );
var normMatrix = matrix3.normalizeMatrix( currentEntity.transform.local ) ;
//currentEntity.mesh.boundingBox = new boundingBox();
//currentEntity.mesh.boundingBox.fitBoxToPoints_( currentMesh.subMeshes[0].vertices, normMatrix );
scene.addEntity( currentEntity, currentEntity.transform.local, materialCache );
}
//}
parentEntity.addChild(currentEntity);
}
} else {
parentEntity.addChild(currentEntity);
}
//if(child.name == "Bip001") {
//this.parseSkeleton( child );
//}
if(assimpNode.children) {
var children = assimpNode.children;
for(var i = 0; i < children.length; i++) {
var child = children[i];
this.parseNode(currentAssimpJson, child, currentEntity, scene, materialCache);
}
}
//console.log(this.engine.system.scene);
}
buildModels( materialCache ) {
var scene = this.scene;
//var materialCache = this.materialCache;
var rootEntity = new entity(this.engine);
rootEntity.name = "root";
rootEntity.transform.world = matrix4.identity();
//this.engine.system.scene.rootEntity = rootEntity;
scene.rootEntity = rootEntity;
if(materialCache) {
for(var c = 0; c<materialCache.length; c++) {
var materialInfo = materialCache[c];
/*
var currentMaterial = new material( );
var diffuseTexture = materialInfo.diffuseTexture; //kepler.resources.getTexture( materialInfo.name + "_diffuse");
if(diffuseTexture) {
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
//currentMaterial.addTexture(diffuseSampler);
console.log(materialInfo.name + "_diffuse", currentMaterial);
} else{
console.log("noo _diffuse", currentMaterial);
}
var normalTexture = kepler.resources.getTexture(materialInfo.name + "_normal");
if(normalTexture) {
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
//currentMaterial.addNormal(normalSampler);
}
var roughnessTexture = kepler.resources.getTexture(materialInfo.name + "_normal");
if(roughnessTexture) {
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
//currentMaterial.addRoughness(roughnessSampler);
}
var depthTexture = kepler.resources.getTexture(materialInfo.name + "_depth");
if(depthTexture) {
//var roughnessSampler = new sampler2D(this.engine);
//roughnessSampler.addTexture(depthTexture);
//material.addDisplacement(roughnessSampler);
}
currentMaterial.diffuseColor = materialInfo.diffuseColor;
currentMaterial.roughness = materialInfo.roughness;
currentMaterial.alpha = materialInfo.opacity;
//var shadingModelID = this.getShadingIdByEntityName(material.id);
//material.setShadingModelID(shadingModelID);
//currentMaterial.create();
materialCache[c] = currentMaterial;
*/
}
var models = this.models;
// matrix4.fromArray( rootnode.transformation );
for(var c = 0; c<models.length; c++) {
var currentAssimpJson = models[c];
var rootnode = currentAssimpJson.rootnode;
var children = rootnode.children;
this.parseNode(currentAssimpJson, rootnode, rootEntity, scene, materialCache);
}
}
}
parseSkeleton( child ) {
this.skeleton = this.engine.createObject("skeleton");
this.skeleton.parse(child, this.rootnode);
this.skeleton.parseAnimation(this.animations[0].channels);
var bones = this.skeleton.bones;
for(var c = 0; c<bones.length; c++) {
var bone = bones[c];
this.skeleton.animate(bone, 0);
var transform = bone.globalTransformation;
var mesh = this.meshes[1];
var currentEntity = new entity(this.engine);
//var diffuseTexture = kepler.resources.getTexture(mesh.material.name + "_diffuse");
//var diffuseSampler = new sampler2D(this.engine);
//diffuseSampler.texture = diffuseTexture;
var material = mesh.material;
//material.addTexture(diffuseSampler);
mesh.addMaterial(material);
currentEntity.addMesh(mesh);
currentEntity.bone = bone;
currentEntity.transform.world = transform;
bone.entity = currentEntity;
//this.engine.system.scene.addEntity(entity);
}
//this.animate();
//console.log(this.skeleton);
}
animate( ) {
var entitys = this.scene.getEntitys();
for(var c = 0; c<entitys.length; c++) {
var bone = entitys[c].bone;
if(bone) {
var bone = this.skeleton.animate(bone, floor(asdasd/2));
entitys[c].transform.world = bone.globalTransformation;
}
}
}
getPropertyByName( properties, name, semantic ) {
for(var c = 0; c<properties.length; c++) {
var property = properties[c];
if(property.key == name && property.semantic == semantic)
return property;
}
return false;
}
}
export {assimp as default};

22
engine/bone.js Executable file
View File

@@ -0,0 +1,22 @@
kepler.bone(){
this.isRoot;
this.name;
this.parent;
this.children = [];
this.transformation;
this.globalTransformation;
this.offsetMatrix;
this.positionkeys;
this.rotationkeys;
this.currentAnimationMatrix;
this.entity;
}
kepler.bone.prototype.addChild( bone ) {
this.children.push( bone );
}

59
engine/boundingBox.js Executable file
View File

@@ -0,0 +1,59 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import {matrix3, vector3} from './math.js';
/**
* Boundingbox
**/
class boundingBox {
maxExtent = [0, 0, 0];
minExtent = [0, 0, 0];
intersectionVector;
/**
* make boundingbox as big as point cloud
* @param {(array)} points
**/
fitBoxToPoints_( points, rotationMatrix ) {
var minVector;
for (var index = 0; index < 3; ++index) {
this.maxExtent[index] = this.minExtent[index] = points[index];
for (var i = 1; i < points.length / 3; ++i) {
var point = [points[i * 3], points[(i * 3) + 1], points[(i * 3) + 2]] ;
if(rotationMatrix){
var translation = rotationMatrix[3];
if(translation) {
point = vector3.add([translation[0], translation[1], translation[2]], point);
}
point = matrix3.transformPoint(rotationMatrix, point);
}
//if(this.minExtent[index] > point[i] && index == 1)
//var minVector = point;
this.minExtent[index] = Math.min(this.minExtent[index], point[index]);
this.maxExtent[index] = Math.max(this.maxExtent[index], point[index]);
}
}
this.intersectionVector = minVector;
this.valid = true;
}
}
export {boundingBox as default};

239
engine/camera.js Executable file
View File

@@ -0,0 +1,239 @@
/*
* Copyright 2013, kaj dijkstra,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import {math, vector2, vector3, matrix4} from './math.js';
/**
* Camera Object
**/
class camera{
constructor( engine ){
this.yaw = 0;
this.pitch = 30;
this.roll = 0;
this.distance = 5.35;
//this.distance = .05;
this.fov = 55;
this.eye = new vector3(0,0,0);
this.target = new vector3(0,0,0);
this.up = new vector3(0, 1, 0);
this.view;
this.projection;
this.worldViewProjection;
this.target;
this.frustumCorners;
this.center = new vector3(0, 1, 0);
this.rotationSpeed = .1;
this.lastPriority = 0;
this.mode = "orbit";//freeLook, orbit
this.fieldOfView = 65;
this.far = 1000;
this.near = 0.004;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
/**
* Set camera position
* @param {(vector3)} position you want to set
**/
setPosition (a) {
this.center = a;
};
/**
* get position of camera
* @return {(vector3)} camera position
**/
getPosition () {
return this.center;
};
/**
* Move camera
* @param {(vector3)}
**/
move (a) {
this.center = kepler.vector3.add(a, this.center);
};
/**
* Set camera direction
* @param {(vector3)}
**/
setDirection ( normalizedVector ) {
this.target = normalizedVector;
};
/**
* get camera direction
* @param {(vector3)}
**/
getDirection () {
return this.target;
};
/**
* get camera up vector
* @param {(vector3)}
**/
getUp () {
return this.up;
};
/**
* get camera right (Depricated)
* @param {(vector3)}
**/
getRight () {
};
/**
* Rotate camera (Depricated)
* @param {(vector3)}
**/
rotate (x,y,z) {
};
/**
* set camera Orientation (Depricated)
* @param {(vector3)}
**/
setOrientation () {
};
/**
* Calculate new up vector to prevent camera flipping on 90 or something degrees.
**/
checkup () {
var that = this;
if(that.pitch<=0)
that.pitch += 360;
if(((that.pitch+90)/180)%2<=1)
that.up = new vector3(0,1,0);
else
that.up = new vector3(0,-1,0);
};
/**
* update camera orbit position.
**/
UpdateOrbit (yaw, pitch) {
this.yaw += yaw * this.rotationSpeed;
this.pitch += pitch * this.rotationSpeed;
this.checkup();
};
/**
* Orbit camera.
**/
orbit() {
this.yaw += .2;
var timeNow = new Date().getTime();
if (kepler.lastTime != 0) {
var elapsed = timeNow - kepler.lastTime;
}
var mix = Math.max(0, Math.min(1, elapsed/120));
var smooth = vector2.interpolate( this.viewport.events.clientMouse,
this.viewport.events.oldMousPos,
mix );
this.viewport.events.mouseVerschil = [this.viewport.events.clientMouse[0] - this.viewport.events.oldMousPos[0], this.viewport.events.clientMouse[1] - this.viewport.events.oldMousPos[1]];
this.viewport.events.oldMousPos = this.viewport.events.clientMouse;
if( this.viewport.events.mouseDown[1] || this.viewport.events.mouseDown[2] ) {
if( this.viewport.events.mouseVerschil[0]!=0 || this.viewport.events.mouseVerschil[1]!=0 ) {
this.UpdateOrbit( -this.viewport.events.mouseVerschil[0] , this.viewport.events.mouseVerschil[1] );
}
}
if(this.yaw > 360)
this.yaw -=360;
if(this.yaw < 0)
this.yaw +=360;
if(this.pitch > 360)
this.pitch -=360;
if(this.pitch < 0)
this.pitch +=360;
var beginVector = new vector3( 0, 0, -this.distance );
var yawMatrix = matrix4.rotationY( math.degToRad(this.yaw) );
var pitchMatrix = matrix4.rotationX( math.degToRad(this.pitch) );
var transMatrix = matrix4.mul(pitchMatrix, yawMatrix);
this.target = this.center;
this.eye = vector3.add( matrix4.transformDirection(transMatrix, beginVector), this.target);
this.projection = matrix4.perspective(math.degToRad(this.fov), this.viewport.width / this.viewport.height, this.near, this.far);
this.view = matrix4.lookAt(this.eye, this.target, this.up);
this.worldViewProjection = matrix4.mul(this.view, this.projection);
};
updateMatrix() {
this.projection = matrix4.perspective(math.degToRad(this.fov), this.engine.system.width / this.engine.system.height, this.near, this.far);
this.view = matrix4.lookAt(this.eye, this.target, this.up);
//console.log(this.eye, this.target, this.up, matrix4.lookAt(this.eye, this.target, this.up))
this.worldViewProjection = matrix4.mul(this.view, this.projection);
}
/**
* Update camera matrices
**/
update() {
this.orbit();
}
}
export {camera as default};

71
engine/defaultRenderPass.js Executable file
View File

@@ -0,0 +1,71 @@
import framebuffer from './framebuffer.js';
import sampler2D from './sampler2D.js';
import {math, vector3, matrix4} from './math.js';
import samplerCube from './samplerCube.js';
import shader from './shader.js';
class defaultRenderPass {
isDefault = true;
realtime = true;
updated = false;
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepareDefault() {
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D( );
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer( );
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
//this.shader = new shader();
//this.shader.createFromFile("shaders/template.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
}
render() {
if(this.renderToViewport) {
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, null );
} else {
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );
}
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.viewport.quad.draw( this.shader );
this.updated = true;
}
}
export {defaultRenderPass as default};

162
engine/entity.js Executable file
View File

@@ -0,0 +1,162 @@
/*
* Copyright 2012, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import transform from './transform.js';
import {matrix4} from './math.js';
/**
* Entity object
**/
class entity{
constructor( ) {
this._className = 'entity';
this.subEntitys = [];
this.name;
this.mesh;
this.drawType = gl.TRIANGLES;
this.transform = new transform();
this.transform.entity = this;
this.bone = false;
this.children = [];
this.parent = false;
this.objectTransform;
this.attenuation = 1.0;
this.sourceRadius = 0.4;
this.sourceLength = 0.2;
this.attenuation = 1.;
this.sourceRadius = 0.0;
this.sourceLength = 0.0;
this.id = kepler.entityID++;
this.type = "Actor";
}
/**
* Translate entity to coordinate
* @param {(float x, float y, float z)} Position
**/
translateTo( x, y, z ) {
this.transform.world = matrix4.translate(matrix4.identity(), kepler.vector3(x,y,z) );
}
addChild( entity ) {
entity.parent = this;
this.children.push(entity);
}
getChildren() {
return this.children;
}
getChildByName( name ) {
for(var c=0;c<this.childen.lenght; c++) {
if(this.childen[c].name == name)
return this.childen[c];
}
}
getParent() {
return this.parent;
}
/**
* add mesh to entity
* @param {(meshObject)} mesh
**/
addMesh(mesh) {
//entity.setViewport( this.viewport );
this.mesh = mesh;
this.mesh.entityID = this.id;
this.mesh.material.entityID = this.id;
var subMeshes = this.mesh.subMeshes;
for(var c = 0;c<subMeshes.length; c++) {
var subMesh = subMeshes[c];
var newSubEntity = {};//kepler.createObject("subEntity");
newSubEntity.subMesh = subMesh;
this.addSubEntity(newSubEntity);
}
};
/**
* add subEntity to entity
* @param {(subEntityObject)} subEntity
**/
addSubEntity(subEntity) {
this.subEntitys.push(subEntity);
};
/**
* get subentity from entity
**/
getSubEntitys() {
return this.subEntitys;
};
/**
* update Uniforms
* @param {(subEntityObject)} subEntity
**/
updateUniforms() {
var shader = this.shader;
var transform = this.transform;
}
/**
* get updated 4x4 world matrix
**/
getUpdatedWorldMatrix() {
var children = this.getChildOfNode(this, []).reverse();
var transform = matrix4.identity();
for(var c = 0; c<children.length;c++) {
var currentParent = children[c];
transform = matrix4.mul(currentParent.transform.world, transform);
}
//transform = transform;//matrix4.scale(this.transform.world, [100, 100, 100]);
return transform;
}
getChildOfNode(node, children){
children.push(node);
if(node.parent)
return this.getChildOfNode(node.parent, children);
else
return children;
}
}
export {entity as default};

210
engine/eventManager.js Executable file
View File

@@ -0,0 +1,210 @@
/**
* Kepler - Core
*
* All rights reserved.
*
* Author: Kaj Dijksta
*
**/
import keplerEngine from './kepler.js';
import {vector2, vector3} from './math.js';
//import vector2 from './math.js';
//import vector3 from './math.js';
/**
* Event Manager
* Manage all mouse and keyboard events in this class
*/
class eventManager {
constructor( viewport ){
this.tempMouse = new vector2(0,0);
this.oldMousPos = new vector2(0,0);
this.mouseVerschil = new vector2(0,0);
this.mouseDown = new vector3(0,0,0);
$(viewport.canvas).data("viewport", this.viewport);
viewport.canvas.addEventListener("mousemove", function(e){
kepler.viewport = viewport;
viewport.events.mouseMoveHandler(e, viewport);
});
viewport.canvas.addEventListener("mousedown", function(e){ viewport.events.mouseDownHandler(e, viewport); });
viewport.canvas.addEventListener("mouseup", function(e){ viewport.events.mouseUpHandler(e, viewport); });
window.addEventListener("keydown", function(e){ viewport.events.keyDownHandler(e, kepler.viewport); });
window.addEventListener("keyup", function(e){ viewport.events.keyUpHandler(e, kepler.viewport); });
this.lastTime = new Date().getTime();
this.elapsed = 0;
this.timeNow = 0;
this.clientMouse = new vector2(0,0);
this.keysDown = false;
}
setViewport( viewport ){
this.viewport = viewport;
}
/**
* Mouse over event handler.
* @param {(event)} event.
**/
mouseMoveHandler ( e, viewport ) {
// console.log(viewport);
this.tempMouse = [ e.screenX, e.screenY ];
this.clientMouse = [ e.screenX , e.screenY ];
if( this.mouseDown[1] || this.mouseDown[2] )
this.lastTime = new Date().getTime();
if(!this.oldMousPos)
this.oldMousPos = this.tempMouse;
};
/**
* Mouse down event handler.
* @param {(event)} event.
*/
mouseDownHandler (e, viewport) {
switch(e.button)
{
case 0:
this.mouseDown[1] = true;
if(this.keysDown == 16)
readPixel();
break;
case 1:
this.mouseDown[0] = true;
break;
case 2:
this.mouseDown[2] = true;
break;
}
}
/**
* Mouse up event handler
* @param {(event)} event.
**/
mouseUpHandler ( e, viewport ) {
switch(e.button)
{
case 0:
this.mouseDown[1] = false;
break;
case 1:
this.mouseDown[0] = false;
break;
case 2:
this.mouseDown[2] = false;
break;
}
}
/**
* Key down event handler
**/
keyDownHandler ( e, viewport ) {
var mainPlayer = viewport.mainPlayer;
switch(e.keyCode) {
case 68: // a
mainPlayer.right = false;
mainPlayer.left = true;
break;
case 65: // d
mainPlayer.left = false;
mainPlayer.right = true;
break;
case 87: //w
mainPlayer.backward = false;
mainPlayer.forward = true;
break;
case 83: //s
mainPlayer.forward = false;
mainPlayer.backward = true;
break;
case 16: //shift
viewport.mainPlayer.moveSpeed = .39;
this.keysDown = 16;
break;
case 90:
mainPlayer.down = true;
break;
case 32:
mainPlayer.up = true;
break;
case 67://v
break;
}
this.keysDown = e.keyCode;
}
/**
* Key up event handler
**/
keyUpHandler(e, viewport)
{
var mainPlayer = viewport.mainPlayer;
switch(e.keyCode)
{
case 65: // a
//g_animate = false;
break;
}
switch(e.keyCode) {
case 68: // a
mainPlayer.left = false;
break;
case 65: // d
mainPlayer.right = false;
break;
case 87: //w
mainPlayer.forward = false;
break;
case 83: //s
mainPlayer.backward = false;
break;
case 16: // shift
viewport.mainPlayer.moveSpeed = .3;
break;
case 90:
mainPlayer.down = false;
break;
case 32:
mainPlayer.up = false;
break;
case 67://v
break;
}
this.keysDown = false;
}
}
export {eventManager as default};

296
engine/framebuffer.js Executable file
View File

@@ -0,0 +1,296 @@
class framebuffer{
constructor( ){
this.width = 1024;
this.height = 1024;
this._className = "_framebuffer";
this.glFramebuffer;
this.framebuffers = [];
this.renderbuffers = [];
this.face = false;
this.renderType = '2d';
this.samplers = []; // render to samplers
//GL_DEPTH_ATTACHMENT
this.multiSample = false;
this.msaaFramebuffer;
this.msaaColorRenderBuffer;
this.msaaDepthRenderBuffer;
this.MSAA_level = 4;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
this.target = this.gl.TEXTURE_2D;
this.type = this.gl.FLOAT;
this.attachment = this.gl.COLOR_ATTACHMENT0;
}
addSampler( sampler, face ) {
sampler.setViewport( this.viewport );
this.samplers.push( sampler );
if( face ){
this.face = face;
}
}
addCubeSampler( sampler ) {
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_X);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
this.samplers.push( sampler );
}
getSampler( ) {
return this.samplers[0];
}
/**
* Create framebuffer
* @param {(int)} width
* @param {(int)} height
* @param {(object)} properties
**/
create() { //type, depth
//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
var attachments = [];
this.glFramebuffer = this.gl.createFramebuffer();
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.glFramebuffer);
this.renderbuffer = this.gl.createRenderbuffer();
this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.renderbuffer);
this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT32F, this.width, this.height);
this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
//}
for(var c = 0; c<this.samplers.length; c++) {
var sampler = this.samplers[c];
sampler.isFramebuffer = true;
sampler.internalFormat = this.gl.RGBA32F;
if(this.target == this.gl.TEXTURE_2D) {
sampler.setTarget( this.viewport );
var textures = sampler.getTextures();
} else {
//var textures = [ sampler.getTexture( this.face ) ];
var textures = sampler.getTextures( );
}
for(var b = 0; b<textures.length; b++) {
var textureObject = textures[b];
//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
if( this.samplers.length == 1 ) {
var attachment = this.attachment;
} else {
switch( c ) {
case 0:
var attachment = this.gl.COLOR_ATTACHMENT0
break;
case 1:
var attachment = this.gl.COLOR_ATTACHMENT1;
break;
case 2:
var attachment = this.gl.COLOR_ATTACHMENT2;
break;
case 3:
var attachment = this.gl.COLOR_ATTACHMENT3;
break;
}
}
attachments.push( attachment );
this.gl.bindTexture( sampler.target, textureObject.glTexture );
if( this.multiSample ) {
this.gl.texParameteri( this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
} else {
switch( sampler.filter ) {
case this.gl.NEAREST:
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
break;
case this.gl.LINEAR:
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
break;
default:
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
}
if( this.multiSample ) {
var levels = 1;
this.gl.texStorage2D( this.gl.TEXTURE_2D, levels, this.gl.RGBA32F, this.width, this.height);
this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, textureObject.glTexture, 0);
} else {
this.gl.texImage2D( textureObject.face, 0, sampler.internalFormat, this.width, this.height, 0, sampler.format, sampler.type, null);
this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, attachment, textureObject.face, textureObject.glTexture, 0);
}
//this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
//this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
//const internalFormat = this.gl.RGBA32F;
//this.gl.framebufferTexture2D(this.gl.READ_FRAMEBUFFER, attachment, texture.face, texture.glTexture, 0);
textureObject.attachment = attachment;
//textureObject.dataType = 'framebuffer'; // weird bug when ob
textureObject.width = this.width;
textureObject.height = this.height;
textureObject.data = textureObject.glTexture;
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
}
}
//}
//this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
//this.gl.renderbufferStorageMultisample();
//console.log(this, textureObject);
if(this.samplers.length > 1) {
//kepler.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(attachments);
this.gl.drawBuffers(attachments);
}
if (this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER) != this.gl.FRAMEBUFFER_COMPLETE) {
alert("this combination of attachments does not work");
}
//this.gl.bindFramebuffer(this.gl.TEXTURE_2D, null);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
//this.gl.bindFramebuffer(this.gl.RENDERBUFFER, null);
}
}
export {framebuffer as default};

478
engine/kepler.js Executable file
View File

@@ -0,0 +1,478 @@
/**
* Kepler - Core
*
* All rights reserved.
*
*/
import { math, matrix4 } from './math.js';
import renderSystem from './renderSystem.js';
import assimp from './assimp.js';
import preloader from './preloader.js';
import texture from './texture.js';
import sampler2D from './sampler2D.js';
import resourceManager from './resourceManager.js';
import pluginManager from './pluginManager.js';
import entity from './entity.js';
import material from './material.js';
import utils from './utils.js';
import viewport from './viewport.js';
class keplerEngine
{
gl;
math;
resources;
events;
system;
mainCamera;
mainPlayer;
assimpLoader;
// public functions
init;
callback;
samplerId = 0;
samplerCubeID = 0;
global_material_id = 0;
entityID = 0;
/**
* Initialize Kepler Engine
*/
constructor() {
this.math = new math();
this.viewports = new Array();
var canvas = document.getElementById("keplerEngine");
this.resources = new resourceManager( this );
this.math = new math();
this.assimpLoader = new assimp();
}
addViewport(viewport){
this.viewports.push(viewport);
}
/**
* Application
*/
application( ) {
var viewports = kepler.viewports;
for(var c = 0; c<viewports.length; c++) {
var viewport = viewports[c];
viewport.system.createRenderPasses();
}
this.resources.finishCallback = function(){
kepler.tick();
}
this.resources.loadNextTexture();
}
registerPlugin( plugin ) {
this.plugins.addPlugin( plugin );
}
render(){
var viewports = kepler.viewports;
for(var c = 0; c<viewports.length; c++) {
var viewport = viewports[c];
viewport.render();
viewport.system.render();
}
}
/**
* Tick
*/
tick() {
requestAnimFrame( this.tick.bind( this ) );
this.render();
}
/**
* create kepler object
* @param {string} name of class
*/
createObject( className ) {
var instance = kepler[ className ];
var object = new instance;
return object;
};
/**
* load url
* @param {string} url
*/
loadTextFileSynchronous(url) {
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
if (request.overrideMimeType) {
request.overrideMimeType('text/plain');
}
} else if (window.ActiveXObject) {
request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
} else {
throw 'XMLHttpRequest is disabled';
}
request.open('GET', url, false);
request.send(null);
if (request.readyState != 4) {
throw error;
}
return request.responseText;
}
/*
* Create error texture
*/
createErrorTexture() {
var dataArray = [];
var width = 512;
var height = 512;
for( var y = 0; y < height; y++ )
{
for( var x = 0; x < width; x++ )
{
dataArray.push(x / width);
dataArray.push( y / width);
dataArray.push( x / x / width);
dataArray.push( y * x / width);
}
}
var text = this.textureFromArray(dataArray, width, height, true);
var sampler = new sampler2D( this );
sampler.texture = text;
this.errorTexture = sampler;
}
/**
* Texture from array
* @param {(array)} array
* @param {(float)} width
* @param {(float)} height
* @param {(boolean)} is_float
**/
textureFromArray( array, width, height, is_float ) {
var textureObject = new texture( this );
if( is_float ) {
textureObject.data = new Float32Array( array );
textureObject.dataType = 'float';
} else {
textureObject.data = new Int32Array( array );
textureObject.dataType = 'int';
}
textureObject.width = width;
textureObject.height = height;
return textureObject;
}
removeElementById(id)
{
return (elem=document.getElementById(id)).parentNode.removeChild(elem);
}
/**
* Texture from typed array
* @param {(typedArray)} typedArray
* @param {(float)} width
* @param {(float)} height
* @param {(viewport)} viewport
**/
textureFromTypedArray( typedArray, width, height ) {
var textureObject = new texture( );
textureObject.data = typedArray;
textureObject.dataType = 'int';
textureObject.width = width;
textureObject.height = height;
return textureObject;
}
/**
* Texture from typed array 32 bit
* @param {(array)} Array
* @param {(float)} width
* @param {(float)} height
**/
textureFromFloat32Array(array, width, height) {
texture = new texture( this );
texture.data = array;
texture.dataType = 'float';
texture.width = width;
texture.height = height;
return texture;
}
/**
* Texture from typed int array 32 bit
* @param {(array)} Array
* @param {(float)} width
* @param {(float)} height
**/
textureFromInt32Array(array, width, height) {
texture = new texture( this );
texture.data = 'int';
texture.dataType = array;
texture.width = width;
texture.height = height;
return texture;
}
dummyTextureFromImage() {
}
/**
* Texture from dom image
* @param {(dom object image)} image
**/
textureFromImage( image, viewport ) {
var textureObject = new texture( );
textureObject.setViewport( viewport );
textureObject.data = image;
textureObject.dataType = 'image';
textureObject.width = image.width;
textureObject.height = image.height;
return textureObject;
}
/**
* Texture from DDS
* @param {(array)} image
**/
textureFromDDS( data ) {
texture = new texture( this );
texture.data = data;
texture.dataType = 'COMPRESSED_RGBA';
texture.width = data.width;
texture.height = data.height;
console.log(texture);
return texture;
}
/**
* Create sampler
* @param {TextureOBject} texture
* @param {Canvas} textureCanvas
*/
createSampler(texture, textureCanvas) {
var image = texture.image;
var width = image.width;
var height = image.height;
if(textureCanvas) {
this.gl.bindTexture(this.gl.TEXTURE_2D, this.gl.createTexture());
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, texture);
} else {
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, texture.image);
}
if (isPowerOfTwo(width) && isPowerOfTwo(height)){
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
} else {
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
}
/**
* Create sampler from Canvas
* @param {Canvas} canvas
* @param {int} idx
*/
createSamplerFromCanvas(canvas, idx) {
var texture = this.gl.createTexture();
this.gl.activeTexture(this.gl.TEXTURE0 + idx);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, canvas);
if (isPowerOfTwo(canvas.width) && isPowerOfTwo(canvas.height)){
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
} else {
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
texture._className = 'textaaaure';
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
return texture;
}
/**
* Check if int is power of two
* @param {int} number
*/
isPowerOfTwo(x) {
return (x & (x - 1)) == 0;
}
/**
* check if object is array
* @return {(boolean)}
**/
is_array(input){
return typeof(input)=='object'&&(input instanceof Array);
}
/**
* Create Texture from pixel array
* @param {array} 2x2 array with pixel colors
* @param {int} width
* @param {int} height
*/
textureFromPixelArray(dataArray, width, height) {
var dataTypedArray = new Float32Array(dataArray);
var texture = this.gl.createTexture();
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
this.gl.activeTexture(this.gl.TEXTURE0 + ++samplerId);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, this.gl.RGBA, this.gl.FLOAT, dataTypedArray);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
texture._className = 'texture';
return texture;
}
}
export {keplerEngine as default};

39
engine/light.js Executable file
View File

@@ -0,0 +1,39 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* light
**/
kepler.light(){
this.position = [190.0,20.0,100.0];
this.target = [0,0,0];
this.up = [0,1,0];
this.projection;
this.view;
this.viewProjection;
this.far = 2420;
this.near = 0.1;
this.type = 'directional';
this.update();
}
/**
* update light
**/
kepler.light.prototype.update(){
var matrix4 = kepler.matrix4;
this.projection = matrix4.perspective(kepler.math.degToRad(45), kepler.width / kepler.height, this.near, this.far);
this.view = matrix4.lookAt(this.position, this.target, this.up);
this.viewProjection = matrix4.mul(this.view, this.projection)
}

396
engine/linePrimitives.js Executable file
View File

@@ -0,0 +1,396 @@
/*
* Kepler
*
*/
import mesh from './mesh.js';
import entity from './entity.js';
import material from './material.js';
import sampler2D from './sampler2D.js';
import {math, vector2, vector3, matrix4} from './math.js';
/**
* primitive object
**/
class linePrimitives{
constructor( engine ) {
this.indices;
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
createLineCubeVertices = function(size, opt_matrix) {
var k = size / 2;
var vertices = [
[-k, -k, -k],
[+k, -k, -k],
[-k, +k, -k],
[+k, +k, -k],
[-k, -k, +k],
[+k, -k, +k],
[-k, +k, +k],
[+k, +k, +k]
];
var indices = [
[0, 1],
[1, 3],
[3, 2],
[2, 0],
[4, 5],
[5, 7],
[7, 6],
[6, 4],
[0, 4],
[1, 5],
[2, 6],
[3, 7]
];
//var vertexInfo = o3djs.lineprimitives.createLineVertexInfo();
//var positionStream = vertexInfo.addStream(3, o3djs.base.o3d.Stream.POSITION);
var vertexArray = [];
var indexArray = [];
for (var v = 0; v < vertices.length; ++v) {
vertexArray.push( vertices[v][0], vertices[v][1], vertices[v][2] );
}
for (var i = 0; i < indices.length; ++i) {
indexArray.push(indices[i][0], indices[i][1]);
}
var newMesh = new mesh(this.engine);
var normalData = [];
var textureCoordData = [];
newMesh.shape = 2;
newMesh.createMeshFromArrays( indexArray, vertexArray, false, false );
newMesh.draw_type = this.gl.LINES;
return newMesh;
}
/**
* get frustum corner coordinates
* @param {(matrix4)} projection
* @param {(matrix4)} view
* @param {(matrix4)} world
**/
getFrustumCorners = function(projection, view, world) {
var cornerVertices = [ [-1,1,1],[1,1,1],[1,-1,1],[-1,-1,1],
[-1,1,-1],[1,1,-1],[1,-1,-1],[-1,-1,-1]
];
var viewClone = matrix4.copyMatrix(view);
//viewClone = matrix4.setTranslation(viewClone, [0,0,0]);
//if(world) {
var viewProjection = matrix4.inverse( matrix4.composition(projection, viewClone) );
//} else {
//var viewProjection = matrix4.inverse( projection );
//}
var corners = [];
for(var c =0; c < cornerVertices.length;c++)
{
var vert = cornerVertices[c];
vert.push(0.0);
vert = matrix4.transformPoint(viewProjection, vert);
corners.push(vert);
}
return corners;
};
drawFrustum( projection, view, world ) {
var corners = this.getFrustumCorners(projection, view, world);
console.log("corners",corners);
var vertexArray = [];
var normalArray = [];
var textureArray = [];
var indexArray = [];
for(var c = 0; c<corners.length; c++) {
var corner = corners[c];
vertexArray.push(corner[0], corner[1], corner[2]);
normalArray.push(1,1,1);
textureArray.push(0,c/10);
}
//var cornerVertices = [ [-1,1,-1],[1,1,-1],[1,-1,-1],[-1,-1,-1], //near
// [-1,1,1],[1,1,1],[1,-1,1],[-1,-1,1] ];
//[-1,1],[1,1],[1,-1],[-1,-1]
indexArray.push(0, 1); // z=-1
indexArray.push(1, 2);
indexArray.push(2, 3);
indexArray.push(3, 0);
indexArray.push(5, 1);
indexArray.push(6, 2);
indexArray.push(4, 0);
indexArray.push(7, 3);
indexArray.push(4, 5);// z=1
indexArray.push(5, 6);
indexArray.push(6, 7);
indexArray.push(7, 4);
//console.log("cornersFlat", vertexArray);
//console.log("corners", corners);
var newMesh = new mesh(this.engine);
newMesh.shape = 2;
newMesh.draw_type = this.gl.LINES;
newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );
return newMesh;
}
createLineRingVertices(radius, subdivisions, maxTexCoord, num) {
var vertexArray = [];
var normalArray = [];
var textureArray = [];
var indexArray = [];
// Generate the individual vertices in our vertex buffer.
for (var i = 0; i <= subdivisions; i++) {
var theta = 2 * Math.PI * i / subdivisions;
vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
normalArray.push(Math.cos(theta), 0, Math.sin(theta));
textureArray.push(maxTexCoord * i / subdivisions);
}
// Connect the vertices by simple lines.
for (var i = 0; i < subdivisions; i++) {
indexArray.push(i, i+1);
}
var newMesh = new mesh(this.engine);
newMesh.shape = 2;
newMesh.draw_type = this.gl.LINES;
newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );
return newMesh;
};
createLines(radius, subdivisions, maxTexCoord, num) {
var vertexArray = [];
var normalArray = [];
var textureArray = [];
var indexArray = [];
// Generate the individual vertices in our vertex buffer.
for (var i = 0; i <= subdivisions; i++) {
var theta = 2 * Math.PI * i / subdivisions;
vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
normalArray.push(Math.cos(theta), 0, Math.sin(theta));
textureArray.push(maxTexCoord * i / subdivisions);
}
// Connect the vertices by simple lines.
for (var i = 0; i < subdivisions; i++) {
indexArray.push(i, i+1);
}
var newMesh = new mesh(this.engine);
newMesh.shape = 2;
newMesh.draw_type = this.gl.LINES;
newMesh.createMeshFromArrays( indexArray, vertexArray, normalArray, textureArray );
return newMesh;
};
createLineSphere = function(
pack,
material,
radius,
subdivisionsAxis,
subdivisionsHeight,
opt_matrix) {
var vertexInfo = o3djs.lineprimitives.createLineSphereVertices(
radius,
subdivisionsAxis,
subdivisionsHeight,
opt_matrix);
return vertexInfo.createShape(pack, material);
};
/**
* Creates ring vertices.
* The ring is a circle in the XZ plane, centered at the origin.
* The created ring has position, normal, and 1-D texcoord streams.
* The normals point outwards from the center of the ring.
* The texture coordinates are based on angle about the center.
*
* @param {number} radius Radius of the ring.
* @param {number} subdivisions Number of steps around the ring.
* @param {number} maxTexCoord 1-D texture coordinates will range from 0 to
* this value, based on angle about the center.
* @param {!o3djs.math.Matrix4} opt_matrix A matrix by which to multiply all
* the vertices.
* @return {!o3djs.lineprimitives.LineVertexInfo} The created ring vertices.
*/
createRotationRingVertices(
radius,
subdivisions,
maxTexCoord,
length) {
if (subdivisions < 3) {
alert('subdivisions must be >= 3');
}
var vertexArray = [];
var normalArray = [];
var textureArray = [];
var indexArray = [];
// Generate the individual vertices in our vertex buffer.
for (var i = 0; i <= subdivisions; i++) {
var theta = length * 0.5 * Math.PI * i / subdivisions;
var theta2 = Math.PI * i + 1 / subdivisions;
var outerRadius = radius+1;
//var outer_ring = new vector3(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
//var outer_ring = new vector3(radiusRadius * Math.cos(theta), 0, radiusRadius * Math.sin(theta));
if(i%2 == 0) {
//outer ring
vertexArray.push(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
//inner ring
vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
//outer ring
//vertexArray.push(outerRadius * Math.cos(theta2), 0, outerRadius * Math.sin(theta2));
} else {
//vertexArray.push(radius * Math.cos(theta), 0, radius * Math.sin(theta));
//vertexArray.push(outerRadius * Math.cos(theta), 0, outerRadius * Math.sin(theta));
//vertexArray.push(radius * Math.cos(theta2), 0, radius * Math.sin(theta2));
}
}
// Connect the vertices by simple lines.
for (var i = 0; i < subdivisions; i++) {
indexArray.push(i, i+1, i+2);
}
var newMesh = new mesh(this.engine);
//newMesh.shape = 3;
//newMesh.draw_type = this.gl.LINES;
newMesh.createMeshFromArrays( indexArray, vertexArray, false, false );
return newMesh;
}
getLine(triangleIndex) {
var indexIndex = triangleIndex * 3;
return [this.indices[indexIndex + 0],
this.indices[indexIndex + 1],
this.indices[indexIndex + 2]];
}
setLine = function(lineIndex, index1, index2) {
var indexIndex = lineIndex * 2;
this.indices[indexIndex + 0] = index1;
this.indices[indexIndex + 1] = index2;
}
/**
* Adds a line.
* @param {number} index1 The index of the first vertex of the line.
* @param {number} index2 The index of the second vertex of the line.
*/
addLine(index1, index2) {
this.indices.push(index1, index2);
};
numLines() {
return this.indices.length / 2;
}
}
export {linePrimitives as default};

300
engine/material.js Executable file
View File

@@ -0,0 +1,300 @@
/*
* Copyright 2013-2018, kaj dijkstra,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import shader from './shader.js';
import sampler2D from './sampler2D.js';
/**
* Material
**/
class material{
name = "none";
color;
properties = new Array();
textures = new Array();
normals = new Array();
displacementMaps = new Array();
transparencyMaps = new Array();
roughnessMaps = new Array();
specularMaps = new Array();
diffuseColor = new Array( 256/256, 256/256,1 );
shadingModelID = 0.0;
useParallax = false;
uvScale = 1;
roughness = 0.1; // 0.75;
metallic = 0.1;
reflectance = 0.1;
uvMultiplier = 1.0;
alpha = 1.0;
shader;
id = kepler.global_material_id++;
entityID = 0;
created = false;
updated = false;
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
}
create ( ) {
this.created = true;
this.shader = new shader();
this.shader.definePragma("TEXTURE", (this.textures.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("NORMAL_MAP", (this.normals.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("ROUGHNESS_MAP", (this.roughnessMaps.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("SHADING_MODEL_ID", this.shadingModelID );
this.shader.definePragma("PARALLAX", (this.useParallax) ? 1.0 : 0.0 );
this.shader.definePragma("DEFERRED", 1.0 );
this.shader.createFromFile("shaders/color.shader");
}
updateShader( ) {
if( !this.updated ) {
console.log("shader updated");
var shader = this.shader;
var viewport = kepler.viewports[0];
shader.setUniform("far", viewport.mainCamera.far );
shader.setUniform("reflectionSampler", viewport.system.reflectionSampler );
shader.setUniform("alpha", this.alpha );
shader.setUniform("uvMultiplier", this.uvMultiplier );
shader.setUniform("render_type", 0);
if( this.textures.length > 0 ) {
this.textures[0].anisotropic = 4;
if( this.textures.length > 0 ) {
shader.setUniform("diffuseSampler", this.textures[0] );
}
if( this.transparencyMaps.length > 0 ) {
shader.setUniform("transparencyMapSampler", this.transparencyMaps[0] );
}
if( this.normals.length > 0 ) {
shader.setUniform("normalSampler", this.normals[0] );
}
if( this.roughnessMaps.length > 0 ) {
shader.setUniform("normalSampler", this.roughnessMaps[0] );
}
if( this.displacementMaps.length > 0 ) {
shader.setUniform("heightSampler", this.displacementMaps[0]);
}
} else {
shader.setUniform("diffuseColor", this.diffuseColor );
}
shader.setUniform("shadingModelID", this.shadingModelID );
//shader.setUniform("roughness", this.roughness );
//shader.setUniform("id", this.id );
var shadowNoiseTexure = kepler.resources.getTexture("rotrandom.png");
var shadowNoiseSampler = new sampler2D();
shadowNoiseSampler.addTexture(shadowNoiseTexure);
console.log("shadowNoiseSampler", shadowNoiseSampler);
//if forward
//var depthpass = this.viewport.system.forwardRenderPipeline.getRenderpass("depth")
var depthPasses = this.viewport.system.depthPasses;
var depthpass = depthPasses[0];
shader.setUniform("shadowDepthSampler", depthpass.framebuffer.getSampler() );
shader.setUniform("lightViewProjection", depthpass.viewProjection );
shader.setUniform("lightPosition", depthpass.lightPosition );
shader.setUniform("lightType", depthpass.lightType == "pointLight" ? 0 : 1 );
shader.setUniform("lightDirection", [0.0, -0.7, 0.5] );
console.log("depthpass.lightPosition", depthpass.lightPosition);
shader.setUniform("shadowNoiseSampler", shadowNoiseSampler );
//shader.setUniform("reflectionSampler", viewport.reflectionSampler );
shader.setUniform("shadowBias", .1 );
shader.setUniform("SpotAngles", [30, 0.1]);
shader.setUniform("LightColor", [1, 1, 1] );
shader.setUniform("far", viewport.mainCamera.far );
shader.setUniform("shadowFar", viewport.mainCamera.far );
shader.setUniform("anisotropy", 0.7 );
shader.setUniform("lightGeometry", [1.0 / 85.0, 4.0, 0.1] );
shader.setUniform("clearCoatColor", [1.0, 1.0, 1.0] );
shader.setUniform("lightColor", [1,1,1] ); //colorTemperatureToSRGB(6000.0) );
//shader.setUniform("lightDirection", [0.0, -0.7, 0.5] );
//shader.setUniform("lightPosition", [3, 4, 1] );
shader.setUniform("lightIntensity", .5);
shader.setUniform("environmentLuminance", 0.4);
shader.setUniform("roughness", this.roughness );
shader.setUniform("clearCoatRoughness", this.roughness );
shader.setUniform("clearCoat", 0.3 );
shader.setUniform("clearCoatThickness", 0.2 );
shader.setUniform("clearCoatIOR", .0 );
shader.setUniform("v_metallic", this.metallic );
shader.setUniform("v_reflectance", this.reflectance);
shader.setUniform("cameraPosition", [0,0,0]);
//shader.setUniform("cameraPosition", [0,0,0]);
//shader.update(this.viewport);
this.updated = true;
}
}
updateColor ( id ) {
this.shadingModelID = id;
}
setShadingModelID ( id ) {
this.shadingModelID = id;
}
getShadingModelID ( id ) {
return this.shadingModelID;
}
addProperty (key, value) {
this.properties.push([key, value]);
}
/**
* add texture to material
* @param {(texture)} texture
**/
addTexture(texture) {
this.textures = [];
this.textures.push(texture);
}
/**
* add normal map to material
* @param {(texture)} texture
**/
addNormal(texture) {
this.normals = [];
this.normals.push(texture);
}
/**
* add normal map to material
* @param {(texture)} texture
**/
addRoughness(texture) {
this.roughnessMaps.push(texture);
}
/**
* add transparency map to material
* @param {(texture)} transparentyMap
**/
addTransparentyMap(texture) {
this.transparencyMaps.push(texture);
}
/**
* add displacement map to material
* @param {(texture)} heightmap
**/
addDisplacement( heightmap ) {
this.useParallax = true;
this.displacementMaps.push(heightmap);
}
/**
* add specular map to material
* @param {(texture)} specularMap
**/
addSpecularMap( specularMap ) {
this.specularMaps.push(specularMap);
}
}
export {material as default};

1412
engine/math.js Executable file
View File

File diff suppressed because it is too large Load Diff

738
engine/mesh.js Executable file
View File

@@ -0,0 +1,738 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import subMesh from './subMesh.js';
import boundingBox from './boundingBox.js';
/**
* Mesh object
**/
class mesh{
constructor( ){
this.gl = gl;
this._className = 'mesh';
this.fileName;
this.name = "new";
this.shaderName;
this.vertexIndexBuffer;
this.vertexPositionBuffer;
this.vertexNormalBuffer;
this.textureCoordBuffer;
this.binormalBuffer = false;
this.tangentBuffer = false;
this.materials = [];
this.subMeshes = [];
this.jsonStruture;
this.shader;
this.forwardShader;
this.renderType = "indexed";
this.materialName;
this.materialId = 1.0;
this.useParallax = false;
this.colorInfoShader;
this.infoShader;
this.materialName;
//this.customShader = new shader();
//this.customShader.createLibraryFomFile("shaders/custom.default.shader");
this.heightmap;
this.useNormal = false;
this.draw_type = gl.TRIANGLES;
this.shape = 3;
this.entityID = 0;
};
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
/**
* Set custom shader (Not yet in use)
* @param {(String)} name
**/
setCustomShader( name ) {
this.customShader = new shader();
this.customShader.createLibraryFomFile("shaders/custom."+name+".shader");
}
/**
* Set custom shader (Not yet in use)
* @param {(String)} name
**/
addHeightmap( heightmap ) {
this.heightmap = heightmap;
this.colorInfoShader.setUniform("heightmap", heightmap );
this.infoShader.setUniform("heightmap", heightmap );
}
/**
* set material id
* @param {(int)} material id
**/
setMaterialId( id ) {
this.materialId = id;
//this.colorInfoShader.setUniform("materialId", this.materialId / 256 );
}
/**
* Load mesh from file
* @param {(String)} url to file
**/
loadMeshFromFile( url ) {
this.jsonStruture = JSON.parse(kepler.loadTextFileSynchronous('media/models/'+url));
this.fileName = url;
this.parseLoadedMesh();
}
/**
* Combine displacement and normal data in one texture
* @param {(Array)} displacement data
* @param {(Array)} normal data
* @return {(Sampler)} sampler
**/
combineDisplacementNormal( displacement, normal ) {
var displacementImage = displacement.data;
var normalImage = normal.data;
var canvas = document.createElement('Canvas');
var width = displacement.width;
var height = displacement.height;
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(displacementImage, 0, 0, width, height);
var displacementpixelData = canvas.getContext('2d').getImageData(0, 0, width, height).data;
canvas.getContext('2d').drawImage(normalImage, 0, 0, width, height);
var normalpixelData = canvas.getContext('2d').getImageData(0, 0, width, height).data;
var dataArray = [];
for(var x = 0; x<width; x++) {
for(var y = 0; y<height; y++) {
var index = (x + (y * height) ) * 4;
dataArray.push(normalpixelData[index] / 255);
dataArray.push(normalpixelData[index+1] / 255);
dataArray.push(normalpixelData[index+2] / 255);
dataArray.push(displacementpixelData[index] / 255);
}
}
var text = kepler.textureFromArray(dataArray, width, height, true);
var sampler = new sampler2D();
sampler.texture = dataArray;
return sampler;
}
/**
* Create tangent and binormal vectors (* This is slow!!)
**/
createTangentAndBinormal( ) {
var bn = this.viewport.primitives.createTangentsAndBinormals( this.vertexPositionBuffer,
this.vertexNormalBuffer,
this.textureCoordBuffer,
this.vertexIndexBuffer );
if(bn.tangent) {
var tangentArray = this.viewport.primitives.layoutArray(bn.tangent);
var binormalArray = this.viewport.primitives.layoutArray(bn.binormal);
this.binormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.binormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(binormalArray), this.gl.STATIC_DRAW);
this.binormalBuffer.itemSize = 3;
this.binormalBuffer.numItems = binormalArray.length / 3;
this.binormalBuffer.data = binormalArray;
this.tangentBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.tangentBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(tangentArray), this.gl.STATIC_DRAW);
this.tangentBuffer.itemSize = 3;
this.tangentBuffer.numItems = tangentArray.length / 3;
this.tangentBuffer.data = tangentArray;
}
}
/**
* set mesh name based on the material types that are used
* @param {(MaterialObject)} Material
**/
setName( material ) {
var name = this.name;
if(material.normals.length > 0)
name += "_normal";
if(material.useParallax)
name += "_parallax";
if(material.textures.length > 0)
name += "_texture";
if(material.transparencyMaps.length > 0)
name += "_transparent";
if(material.specularMaps.length > 0)
name += "_specular";
this.shaderName = name;
}
/**
* add material to mesh
* @param {(MaterialObject)} Material
**/
addMaterial( material ) {
if(!material.created) {
material.create();
}
this.material = material;
this.material.setViewport( this.viewport );
this.material.entityID = this.entityID;
/*
this.shader = new shader();
this.shader.definePragma("TEXTURE", (material.textures.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("NORMAL_MAP", (material.normals.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("ROUGHNESS_MAP", (material.roughnessMaps.length > 0) ? 1.0 : 0.0 );
this.shader.definePragma("SHADING_MODEL_ID", material.shadingModelID );
this.shader.definePragma("PARALLAX", (material.useParallax) ? 1.0 : 0.0 );
this.shader.definePragma("DEFERRED", 1.0 );
this.shader.createFomFile("shaders/color.shader");
this.updateShader(material, this.shader);
this.forwardShader = new shader();
this.forwardShader.definePragma("TEXTURE", (material.textures.length > 0) ? 1.0 : 0.0 );
this.forwardShader.definePragma("NORMAL_MAP", (material.normals.length > 0) ? 1.0 : 0.0 );
this.forwardShader.definePragma("ROUGHNESS_MAP", (material.roughnessMaps.length > 0) ? 1.0 : 0.0 );
this.forwardShader.definePragma("SHADING_MODEL_ID", material.shadingModelID );
this.forwardShader.definePragma("PARALLAX", (material.useParallax) ? 1.0 : 0.0 );
this.forwardShader.definePragma("DEFERRED", 0 );
this.forwardShader.createFomFile("shaders/color.shader");
this.updateShader(material, this.forwardShader);
//forwardShader
this.updateMaterial();
*/
}
updateShader( material, shader ) {
shader.setUniform("far", kepler.mainCamera.far );
//this.shader = kepler.resources.getShader("shaders/color.shader");
shader.setUniform("reflectionSampler", kepler.system.reflectionSampler );
if( material.textures.length > 0 ) {
material.textures[0].anisotropic = 4;
if( material.textures.length > 0 ) {
shader.setUniform("diffuseSampler", material.textures[0] );
}
if( material.transparencyMaps.length > 0 ) {
shader.setUniform("transparencyMapSampler", material.transparencyMaps[0] );
}
if( material.normals.length > 0 ) {
shader.setUniform("normalSampler", material.normals[0] );
}
if( material.roughnessMaps.length > 0 ) {
shader.setUniform("normalSampler", material.roughnessMaps[0] );
}
if( material.displacementMaps.length > 0 ) {
shader.setUniform("heightSampler", material.displacementMaps[0]);
}
} else {
shader.setUniform("diffuseColor", material.diffuseColor );
//var color = material.color;
//this.shader.setUniform("rgb", color );
}
shader.setUniform("roughness", material.roughness );
shader.setUniform("id", material.id );
shader.setUniform("clearCoat", 1 );
shader.setUniform("clearCoatThickness", 1 );
shader.setUniform("clearCoatIOR", 1 );
shader.setUniform("anisotropy", 1 );
shader.setUniform("lightIntensity", 2);
shader.setUniform("environmentLuminance", 1 );
shader.setUniform("lightGeometry", [1,1,1] );
shader.setUniform("clearCoatColor", [1,1,1] );
shader.setUniform("lightColor", [1,1,1] );
var sphericalHarmonics = [];
for(var c = 0; c<8; c++) {
sphericalHarmonics.push([1,1,1]);
}
shader.setUniform("sphericalHarmonics", sphericalHarmonics );
}
updateMaterial( ) {
this.shader.setUniform("roughness", this.material.roughness );
this.forwardShader.setUniform("roughness", this.material.roughness );
this.forwardShader.setUniform("alpha", this.material.alpha );
console.log("roughness", this.material.roughness,this.shader );
}
/**
* load object from file >?>
* @param {(string)} url
**/
loadObjFromFile( url ) {
var objText = kepler.loadTextFileSynchronous(url);
var obj = {};
var vertexMatches = objText.match(/^v( -?\d+(\.\d+)?){3}$/gm);
if (vertexMatches)
{
console.log(obj.vertices = vertexMatches.map(function(vertex)
{
var vertices = vertex.split(" ");
vertices.shift();
return vertices;
}));
}
}
/**
* parse mesh, load extra mesh data into buffers
* @param {(string)} url
**/
parseLoadedMesh( url ) {
var subMeshObject = new subMeshObject();
if(this.jsonStruture.indices) {
this.renderType = "indexed";
subMeshObject.indices = this.jsonStruture.indices;
this.vertexIndexBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
//if(kepler.extensions.elementIndexUint)
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(subMeshObject.indices), this.gl.STATIC_DRAW);
//else
// this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(subMeshObject.indices), this.gl.STATIC_DRAW);
this.vertexIndexBuffer.itemSize = 3;
this.vertexIndexBuffer.numItems = subMeshObject.indices.length;
this.vertexIndexBuffer.data = subMeshObject.indices;
} else {
this.renderType = "array";
}
subMeshObject.vertices = this.jsonStruture.positions;
this.vertexPositionBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(subMeshObject.vertices), this.gl.STATIC_DRAW);
this.vertexPositionBuffer.itemSize = 3;
this.vertexPositionBuffer.numItems = subMeshObject.vertices.length / 3;
this.vertexPositionBuffer.data = subMeshObject.vertices;
if(this.jsonStruture.uv) {
subMeshObject.textcoords = this.jsonStruture.uv;
this.textureCoordBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(subMeshObject.textcoords), this.gl.STATIC_DRAW);
this.textureCoordBuffer.itemSize = 2;
this.textureCoordBuffer.numItems = subMeshObject.textcoords.length / 2;
this.textureCoordBuffer.data = subMeshObject.textcoords;
}
if(this.jsonStruture.normals) {
subMeshObject.normals = this.jsonStruture.normals;
this.vertexNormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexNormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(subMeshObject.normals), this.gl.STATIC_DRAW);
this.vertexNormalBuffer.itemSize = 3;
this.vertexNormalBuffer.numItems = subMeshObject.normals.length / 3;
this.vertexNormalBuffer.data = subMeshObject.normals;
}
this.subMeshes.push(subMeshObject);
}
copyMesh( mesh ) {
this.createdBuffers = false;
this.indices = mesh.indices;
this.vertices = mesh.vertices;
this.normals = mesh.normals;
this.textureCoordinates = mesh.textureCoordinates;
this.tangents = mesh.tangents;
this.binormals = mesh.binormals;
}
/**
* Create mesh from arrays
* @param {(array)} indices
* @param {(array)} vertices
* @param {(array)} normals
* @param {(array)} uvs
* @param {(array)} tangents
* @param {(array)} binormals
**/
createMeshFromArrays( indices, vertices, normals, textureCoordinates, tangents, binormals ) {
//todo: loop trough sub meshes
//var subMeshObject = new subMesh();
this.createdBuffers = false;
this.indices = indices;
this.vertices = vertices;
this.normals = normals;
this.textureCoordinates = textureCoordinates;
this.tangents = tangents;
this.binormals = binormals;
/*
if(indices) {
this.renderType = "indexed";
//subMeshObject.indices = indices;
this.vertexIndexBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
//if(kepler.extensions.elementIndexUint)
// this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(subMeshObject.indices), this.gl.STATIC_DRAW);
//else
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indices), this.gl.STATIC_DRAW);
this.vertexIndexBuffer.itemSize = 3;
this.vertexIndexBuffer.numItems = indices.length;
this.vertexIndexBuffer.data = indices;
} else {
this.renderType = "array";
}
//subMeshObject.vertices = vertices;
this.vertexPositionBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertices), this.gl.STATIC_DRAW);
this.vertexPositionBuffer.itemSize = 3;
this.vertexPositionBuffer.numItems = vertices.length / 3;
this.vertexPositionBuffer.data = vertices;
if(uvs) {
//subMeshObject.textcoords = uvs;
this.textureCoordBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(uvs), this.gl.STATIC_DRAW);
this.textureCoordBuffer.itemSize = 2;
this.textureCoordBuffer.numItems = uvs.length / 2;
this.textureCoordBuffer.data = uvs;
}
if(normals) {
//subMeshObject.normals = normals;
this.vertexNormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexNormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(normals), this.gl.STATIC_DRAW);
this.vertexNormalBuffer.itemSize = 3;
this.vertexNormalBuffer.numItems = normals.length / 3;
this.vertexNormalBuffer.data = normals;
}
if(tangents) {
//subMeshObject.tangents = tangents;
this.tangentBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.tangentBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(tangents), this.gl.STATIC_DRAW);
this.tangentBuffer.itemSize = 3;
this.tangentBuffer.numItems = tangents.length / 3;
this.tangentBuffer.data = tangents;
} else {
this.createTangentAndBinormal();
}
if(binormals) {
this.binormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.binormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(binormals), this.gl.STATIC_DRAW);
this.binormalBuffer.itemSize = 3;
this.binormalBuffer.numItems = binormals.length / 3;
this.binormalBuffer.data = binormals;
}
*/
//this.subMeshes.push(subMeshObject);
this.boundingBox = new boundingBox();
this.boundingBox.fitBoxToPoints_( vertices );
}
createBuffers() {
if(!this.createdBuffers) {
if(this.indices) {
this.renderType = "indexed";
this.vertexIndexBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
//if(kepler.extensions.elementIndexUint)
// this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(subMeshObject.indices), this.gl.STATIC_DRAW);
//else
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(this.indices), this.gl.STATIC_DRAW);
this.vertexIndexBuffer.itemSize = this.shape;
this.vertexIndexBuffer.numItems = this.indices.length;
this.vertexIndexBuffer.data = this.indices;
} else {
this.renderType = "array";
}
this.vertexPositionBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.vertices), this.gl.STATIC_DRAW);
this.vertexPositionBuffer.itemSize = 3;
this.vertexPositionBuffer.numItems = this.vertices.length / 3;
this.vertexPositionBuffer.data = this.vertices;
if(this.textureCoordinates) {
this.textureCoordBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.textureCoordBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.textureCoordinates), this.gl.STATIC_DRAW);
this.textureCoordBuffer.itemSize = 2;
this.textureCoordBuffer.numItems = this.textureCoordinates.length / 2;
this.textureCoordBuffer.data = this.textureCoordinates;
}
if(this.normals) {
this.vertexNormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexNormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.normals), this.gl.STATIC_DRAW);
this.vertexNormalBuffer.itemSize = 3;
this.vertexNormalBuffer.numItems = this.normals.length / 3;
this.vertexNormalBuffer.data = this.normals;
}
if(this.tangents) {
this.tangentBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.tangentBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.tangents), this.gl.STATIC_DRAW);
this.tangentBuffer.itemSize = 3;
this.tangentBuffer.numItems = this.tangents.length / 3;
this.tangentBuffer.data = this.tangents;
} else {
if(this.draw_type != this.gl.LINES)
this.createTangentAndBinormal();
}
if(this.binormals) {
this.binormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.binormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.binormals), this.gl.STATIC_DRAW);
this.binormalBuffer.itemSize = 3;
this.binormalBuffer.numItems = this.binormals.length / 3;
this.binormalBuffer.data = this.binormals;
}
this.createdBuffers = true;
}
}
/**
* write content to ext console
* @param {(string)} content
**/
writeConsole(content) {
top.consoleRef=window.open('','myconsole',
'width=350,height=250'
+',menubar=0'
+',toolbar=1'
+',status=0'
+',scrollbars=1'
+',resizable=1')
top.consoleRef.document.writeln(
'<html><head><title>Console</title></head>'
+'<body bgcolor=white onLoad="self.focus()">'
+content
+'</body></html>'
)
top.consoleRef.document.close()
}
/**
* Show tangent
* @param {(subMeshObject)}
**/
showTangent( subMeshObject ) {
writeConsole( this.fileName + ' Tangent ' + JSON.stringify(this.tangentBuffer.data) );
}
/**
* Show Binormal
* @param {(subMeshObject)}
**/
showBinormal( subMeshObject ) {
var tangentArray = this.binormalBuffer.data;
var a = [];
for(var c = 0; c<tangentArray.length;c++){
var s = tangentArray[c];
a[c] = parseFloat(s.toFixed(5));
}
writeConsole( this.fileName + ' binormal ' + JSON.stringify(a) );
}
/**
* add subMeshObject to mesh
* @param {(subMeshObject)}
**/
addsubMeshObject( subMeshObject ) {
this.vertexIndexBuffer = subMeshObject.indexBuffer;
this.vertexPositionBuffer = subMeshObject.vertexBuffer;
this.vertexNormalBuffer = subMeshObject.normalBuffer;
this.textureCoordBuffer = subMeshObject.uvBuffer;
this.tangentBuffer = subMeshObject.tangentBuffer;
this.binormalBuffer = subMeshObject.binormalBuffer;
this.subMeshes.push(subMeshObject);
}
}
export {mesh as default};

212
engine/player.js Executable file
View File

@@ -0,0 +1,212 @@
/*
* Copyright 2012, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import {math, vector3, matrix4} from './math.js';
/**
* Player object
**/
class player
{
constructor( engine ) {
this.position = [0,0,0];
this.groundHeight = this.position[1];
//var math = this.engine.math;
this.velocity = new vector3( 0.1, -0.1, 0.1 );
this.yaw = 0;
this.pitch = 0;
this.roll = 0;
this.strafe = false;
this.right = false;
this.left = false;
this.backward = false;
this.forward = false;
this.up = false;;
this.down = false;;
this.moveSpeed = .02;
this.bounceSpeed = 0.2;
this.gravity = 1.32;
this.direction;
this.damping = 0.6;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
/**
* update object
**/
update() {
if(this.viewport.mainCamera.mode == "orbits") {
var orientation = matrix4.rotationY( math.degToRad(this.yaw-180) );
var groundHeight = this.groundHeight;
if(this.position[1] < groundHeight) {
if(this.forward)
this.velocity[1] = 20;
else
this.velocity[1] *= -this.damping;
if(this.velocity[1] <= 0.2)
this.velocity[1] = 0;
this.position[1] = groundHeight - 0.01;
} else {
this.velocity[1] -= this.gravity;
}
if(Math.abs(this.velocity[0]) <= .2)
this.velocity[0] = 0;
if(Math.abs(this.velocity[2]) <= .2)
this.velocity[2] = 0;
var leftVector = new vector3(-1,0,0);
var rightVector = new vector3(1,0,0);
var forwardVector = new vector3(0,0,1);
var backwardVector = new vector3(0,0,-1);
var totalVector = new vector3(0,0,0);
var forward = matrix4.transformDirection(orientation, forwardVector);
if(this.forward) {
totalVector = vector3.add(totalVector, forward);
}
if(this.backward) {
var backward = matrix4.transformDirection(orientation, backwardVector);
totalVector = vector3.add(totalVector, backward);
}
if(this.strafe)
{
if(this.left) {
var left = matrix4.transformDirection(orientation, leftVector);
totalVector = vector3.add(totalVector, left);
console.log("left", left);
}
if(this.right) {
var right = matrix4.transformDirection(orientation, rightVector);
totalVector = vector3.add(totalVector, right);
}
} else {
if(this.left)
{
this.yaw+=7;
totalVector = vector3.add(totalVector, rightVector );
}
if(this.right)
{
this.yaw-=7;
totalVector = vector3.add(totalVector,leftVector );
}
}
//console.log(totalVector, this.moveSpeed, this.position, this.velocity);
if(totalVector[0]+totalVector[1]+totalVector[2] != 0) {
var normalizedTotal = vector3.normalize(totalVector);
totalVector = vector3.mulScalarVector(this.moveSpeed, normalizedTotal);
this.position = vector3.add(totalVector, this.position);
//this.smoothTransition();
}
//intergration position
//this.positionTransform.identity();
console.log(this.position, this.velocity);
this.position = vector3.add(this.position, this.velocity);
//this.positionTransform.translate(this.position);
//update camera
kepler.mainCamera.center[0] = this.position[0];
kepler.mainCamera.center[1] = this.groundHeight;
kepler.mainCamera.center[2] = this.position[2];
//update rotation
//this.transform.identity();
//this.transform.rotateY(toRad(this.yaw));
} else {
var direction = vector3.normalize(vector3.sub(this.viewport.mainCamera.eye, this.viewport.mainCamera.center));
direction[1] = 0;
var totalVector = [0,0,0];
var leftVector = [1,0,0];
var rightVector = [-1,0,0];
var downVector = [0,-1,0];
var upVector = [0,1,0];
var orientation = matrix4.rotationY(math.degToRad(this.viewport.mainCamera.yaw-180));
if(this.forward) {
totalVector = vector3.add(totalVector, vector3.negativeVector(direction) );
}
if(this.backward) {
totalVector = vector3.add(totalVector, direction);
}
if(this.left) {
var left = matrix4.transformDirection(orientation, leftVector);
totalVector = vector3.add(totalVector, left);
}
if(this.right) {
var right = matrix4.transformDirection(orientation, rightVector);
totalVector = vector3.add(totalVector, right);
}
if(this.down) {
var down = matrix4.transformDirection(orientation, downVector);
totalVector = vector3.add(totalVector, down);
}
if(this.up) {
var up = matrix4.transformDirection(orientation, upVector);
totalVector = vector3.add(totalVector, up);
}
this.direction = totalVector;
totalVector = vector3.mulScalarVector(this.moveSpeed, totalVector);
this.viewport.mainCamera.center = vector3.add(totalVector, this.viewport.mainCamera.center);
}
}
}
export {player as default};

20
engine/plugin.js Executable file
View File

@@ -0,0 +1,20 @@
/*
* Copyright 2019, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* Plugin
**/
class plugin{
resourceCallback;
application;
onRender
}
export {plugin as default};

24
engine/pluginManager.js Executable file
View File

@@ -0,0 +1,24 @@
/*
* Copyright 2019, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* Plugin Manager
**/
class pluginManager{
plugins = [];
addPlugin( plugin ) {
this.plugins.push( plugin );
}
}
export {pluginManager as default};

178
engine/preloader.js Executable file
View File

@@ -0,0 +1,178 @@
class preloader {
constructor( engine ) {
this.engine = engine;
this.items = [];
this.totalBytes = 0;
this.loadedBytes = 0;
/*
this.preloader_holder = document.createElement("div");
var preloader_inner = document.createElement("div");
this.preloader_text = document.createElement("div");
this.preloader_holder.className = "preloader_holder";
preloader_inner.className = "preloader circlechart";
this.preloader_text.className = "preloader_text";
this.preloader_holder.appendChild(preloader_inner);
this.preloader_holder.appendChild(this.preloader_text);
this.bar = new ldBar(".preloader");
*/
//engine.system.canvas.parentElement.appendChild(this.preloader_holder);
//console.log();
//var progressBarLoader = new ProgressBar.Line('.preloader');
//window.ProgressBar
/*
this.bar = new ProgressBar.SemiCircle(preloader_inner, {
strokeWidth: 6,
color: '#FFEA82',
trailColor: '#eee',
trailWidth: 1,
easing: 'easeInOut',
duration: 1400,
svgStyle: null,
text: {
value: '',
alignToBottom: false
},
from: {color: '#FFEA82'},
to: {color: '#ED6A5A'},
// Set default step function for all animate calls
step: (state, bar) => {
bar.path.setAttribute('stroke', state.color);
var value = Math.round(bar.value() * 100);
if (value === 0) {
bar.setText('');
} else {
bar.setText(value);
}
bar.text.style.color = state.color;
}
});
*/
//this.bar.animate(1.0); // Number from 0.0 to 1.0
}
formatSizeUnits(bytes){
if (bytes >= 1073741824) { bytes = (bytes / 1073741824).toFixed(2) + " GB"; }
else if (bytes >= 1048576) { bytes = (bytes / 1048576).toFixed(2) + " MB"; }
else if (bytes >= 1024) { bytes = (bytes / 1024).toFixed(2) + " KB"; }
else if (bytes > 1) { bytes = bytes + " bytes"; }
else if (bytes == 1) { bytes = bytes + " byte"; }
else { bytes = "0 bytes"; }
return bytes;
}
update(name, loaded, total){
if(!total)
var total = 206965373;
//if(loaded != infinity )
$(".preloader_text").text(this.formatSizeUnits(loaded) + " of the " + this.formatSizeUnits(total) );
//console.log(Math.round((loaded/total) * 100) / 100 );
this.engine.bar.set( Math.round((loaded/total) * 100) );
//this.bar.animate( Math.round((loaded/total) * 100) / 100 );
if(total < loaded){
$(".preloader").attr("data-stroke", "green");
}
}
itemByName( name ) {
for(var c = 0; c<this.items.length; c++) {
var item = this.items[c];
if(item.name = name) {
return item;
}
}
}
add( name, size ) {
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
var loadingItem = {};
loadingItem.name = name;
loadingItem.size = clone(size);
console.log('add item', loadingItem );
this.items.push(loadingItem);
if(size)
this.totalBytes += size;
var name_split = name.split("/");
var name_short = name_split[name_split.length-1];
var div = document.createElement("div");
var rand_col = '#'+Math.floor(Math.random()*16777215).toString(16);
name_short = "";
var mbSize = size / 10000;
//if(mbSize > 80)
// $(div).text(name_short ).addClass("loading_item").css({"width": mbSize, "background": rand_col});
loadingItem.div = div;
//$(".preloader").append(div);
}
finish( name ) {
//console.log("finish callback", name, this);
$(".preloader_holder").fadeOut( "slow", function() {
// Animation complete.
});
//var item = this.itemByName(name);
//this.loadedBytes += item.size;
//console.log("finish item", item);
//var div = item.div;
//var percentage = (this.loadedBytes / 53460652);
//this.bar.animate(percentage);
//$(div).animate({width: 0});
}
}
export {preloader as default};

973
engine/primitives.js Executable file
View File

@@ -0,0 +1,973 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import mesh from './mesh.js';
import {vector2, vector3} from './math.js';
console.log(vector3.add([1,1,1], [1,1,1]));
/**
* primitive object
**/
class primitives{
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
/**
* Create plane
* @param {(int)} width
* @param {(int)} depth
* @param {(int)} subdivisionsDepth
* @param {(int)} subdivisionsWidth
* @param {(string)} type
* @param {(int)} index_type
**/
createPlane(width, depth, subdivisionsDepth, subdivisionsWidth, type, index_type) {
var vertices = [];
var indices = [];
var normals = [];
var textureCoordinates = [];
switch(type) {
case "triangleFan":
vertices = getVertices(subdivisionsDepth, subdivisionsWidth);
indices = getIndices(subdivisionsDepth, subdivisionsWidth);
textureCoordinates = getTextCoord(subdivisionsDepth, subdivisionsWidth);
break;
case "triangleStrip":
vertices = createPlaneTriangleStripVerts(subdivisionsDepth, subdivisionsWidth, width, depth, index_type);
indices = createPlaneTriangleStripIndices(subdivisionsDepth, subdivisionsWidth, index_type);
textureCoordinates = createPlaneTriangleStripTextCoords(subdivisionsDepth, subdivisionsWidth);
break;
default:
for (var z = 0; z <= subdivisionsDepth; z++) {
for (var x = 0; x <= subdivisionsWidth; x++) {
var u = x / subdivisionsWidth;
var v = z / subdivisionsDepth;
var vertex = new vector3( width * u - width * 0.5,
0,
depth * v - depth * 0.5);
var normal = new vector3(0, 1, 0);
var textCoord = new vector2(u , (1 - v ));
vertices = vertices.concat(vertex);
normals = normals.concat(normal);
textureCoordinates = textureCoordinates.concat(textCoord);
}
}
var numVertsAcross = subdivisionsWidth + 1;
for (var z = 0; z < subdivisionsDepth; z++) {
for (var x = 0; x < subdivisionsWidth; x++) {
// triangle 1 of quad
var triangle1 = new vector3( (z + 0) * numVertsAcross + x,
(z + 1) * numVertsAcross + x,
(z + 0) * numVertsAcross + x + 1 );
// triangle 2 of quad
var triangle2 = new vector3( (z + 1) * numVertsAcross + x,
(z + 1) * numVertsAcross + x + 1,
(z + 0) * numVertsAcross + x + 1 );
indices = indices.concat(triangle1);
indices = indices.concat(triangle2);
}
}
var planeMesh = new mesh();
planeMesh.createMeshFromArrays( indices, vertices, normals, textureCoordinates);
return planeMesh;
}
//console.log(this);
//return this.createMesh(subMesh.indices, subMesh.vertices, subMesh.textcoords, subMesh.normals);
}
/**
* Create Sphere
* @param {(int)} radius
* @param {(int)} subdivisionsHeight
* @param {(int)} subdivisionsAxis
**/
createSphere(radius, subdivisionsHeight, subdivisionsAxis) {
var latitudeBands = subdivisionsHeight;
var longitudeBands = subdivisionsAxis;
var vertexPositionBuffer;
var vertexNormalBuffer;
var vertexTextureCoordBuffer;
var vertexIndexBuffer;
var vertexPositionData = [];
var normalData = [];
var textureCoordData = [];
for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) {
var theta = latNumber * Math.PI / latitudeBands;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) {
var phi = longNumber * 2 * Math.PI / longitudeBands;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);
var x = cosPhi * sinTheta;
var y = cosTheta;
var z = sinPhi * sinTheta;
var u = 1- (longNumber / longitudeBands);
var v = latNumber / latitudeBands;
normalData.push(x);
normalData.push(y);
normalData.push(z);
textureCoordData.push(u);
textureCoordData.push(v);
vertexPositionData.push(radius * x);
vertexPositionData.push(radius * y);
vertexPositionData.push(radius * z);
}
}
var indexData = [];
for (var latNumber = 0; latNumber < latitudeBands; latNumber++) {
for (var longNumber = 0; longNumber < longitudeBands; longNumber++) {
var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;
indexData.push(first);
indexData.push(second);
indexData.push(first + 1);
indexData.push(second);
indexData.push(second + 1);
indexData.push(first + 1);
}
}
var newMesh = new mesh();
newMesh.setViewport(this.viewport);
newMesh.createMeshFromArrays( indexData, vertexPositionData, normalData, textureCoordData );
return newMesh;
}
/**
* lay out array
* @param {(array)} array
* @param {(string)} output
**/
layoutArray(array) {
var out = [];
for(var c = 0; c<array.length; c++) {
var a = array[c];
if(a)
for(var g = 0; g<a.length; g++) {
out.push(a[g]);
}
}
return out;
}
/**
* Create mesh
* @param {(array)} indexData
* @param {(array)} vertexPositionData
* @param {(array)} textureCoordData
* @param {(array)} normalData
**/
createMesh(indexData, vertexPositionData, textureCoordData, normalData) {
var mesh = {};
if(normalData) {
var vertexNormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexNormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(normalData), this.gl.STATIC_DRAW);
vertexNormalBuffer.itemSize = 3;
vertexNormalBuffer.numItems = normalData.length / 3;
vertexNormalBuffer.data = normalData;
mesh.normalBuffer = vertexNormalBuffer;
}
if(textureCoordData) {
var vertexTextureCoordBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexTextureCoordBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this.gl.STATIC_DRAW);
vertexTextureCoordBuffer.itemSize = 2;
vertexTextureCoordBuffer.numItems = textureCoordData.length / 2;
vertexTextureCoordBuffer.data = textureCoordData;
mesh.uvBuffer = vertexTextureCoordBuffer;
}
var vertexPositionBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexPositionBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), this.gl.STATIC_DRAW);
vertexPositionBuffer.itemSize = 3;
vertexPositionBuffer.numItems = vertexPositionData.length / 3;
vertexPositionBuffer.data = vertexPositionData;
var vertexIndexBuffer = this.gl.createBuffer();
if(indexData) {
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
//if(kepler.extensions.elementIndexUint)
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indexData), this.gl.STATIC_DRAW);
//else
// this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), this.gl.STATIC_DRAW);
vertexIndexBuffer.itemSize = 3;
vertexIndexBuffer.numItems = indexData.length;
vertexIndexBuffer.data = indexData;
}
if(normalData) {
var bn = this.createTangentsAndBinormals( vertexPositionBuffer,
vertexNormalBuffer,
vertexTextureCoordBuffer,
vertexIndexBuffer);
var binormalArray = this.viewport.primitives.layoutArray(bn.binormal);
var binormalBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, binormalBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(binormalArray), this.gl.STATIC_DRAW);
binormalBuffer.itemSize = 3;
binormalBuffer.numItems = binormalArray.length / 3;
binormalBuffer.data = binormalArray;
var tangentArray = this.viewport.primitives.layoutArray(bn.tangent);
var tangentBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, tangentBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(tangentArray), this.gl.STATIC_DRAW);
tangentBuffer.itemSize = 3;
tangentBuffer.numItems = tangentArray.length / 3;
tangentBuffer.data = tangentArray;
mesh.binormalBuffer = binormalBuffer;
mesh.tangentBuffer = tangentBuffer;
}
mesh.vertexBuffer = vertexPositionBuffer;
mesh.indexBuffer = vertexIndexBuffer;
return mesh;
}
/**
* Get element
* @param {(array)} buffer
* @param {(int)} vertexIndex
* @return {(array)} out
**/
getElement(buffer, vertexIndex) {
var startId = buffer.itemSize * vertexIndex;
var out = [];
for(var c = 0; c<buffer.itemSize; c++) {
out.push(buffer.data[c+startId]);
}
return out;
}
/**
* Create Tangent and Binormal vectors
* @param {(array)} positionArray
* @param {(array)} normalArray
* @param {(array)} normalMapUVArray
* @param {(array)} triangles
* @return {(array)} primitive object
**/
createTangentsAndBinormals( positionArray, normalArray, normalMapUVArray, triangles) {
// Maps from position, normal key to tangent and binormal matrix.
var tangentFrames = {};
// Rounds a vector to integer components.
function roundVector(v) {
return [Math.round(v[0]), Math.round(v[1]), Math.round(v[2])];
}
// Generates a key for the tangentFrames map from a position and normal
// vector. Rounds position and normal to allow some tolerance.
function tangentFrameKey(position, normal) {
return roundVector(vector3.scale(position, 100)) + ',' +
roundVector(vector3.scale(normal, 100));
}
// Accumulates into the tangent and binormal matrix at the approximate
// position and normal.
function addTangentFrame(position, normal, tangent, binormal) {
var key = tangentFrameKey(position, normal);
var frame = tangentFrames[key];
if (!frame) {
frame = [[0, 0, 0], [0, 0, 0]];
}
frame[0] = vector3.add(frame[0], tangent);
frame[1] = vector3.add(frame[1], binormal);
tangentFrames[key] = frame;
}
// Get the tangent and binormal matrix at the approximate position and
// normal.
function getTangentFrame(position, normal) {
var key = tangentFrameKey(position, normal);
return tangentFrames[key];
}
var numTriangles = triangles.numItems;
for (var triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex) {
// Get the vertex indices, uvs and positions for the triangle.
var vertexIndices = this.getElement(triangles, triangleIndex);
var uvs = [];
var positions = [];
var normals = [];
for (var i = 0; i < 3; ++i) {
var vertexIndex = vertexIndices[i];
uvs[i] = this.getElement(normalMapUVArray, vertexIndex);
positions[i] = this.getElement(positionArray,vertexIndex);
normals[i] = this.getElement(normalArray,vertexIndex);
}
// Calculate the tangent and binormal for the triangle using method
// described in Maya documentation appendix A: tangent and binormal
// vectors.
var tangent = [0, 0, 0];
var binormal = [0, 0, 0];
for (var axis = 0; axis < 3; ++axis) {
var edge1 = [positions[1][axis] - positions[0][axis],
uvs[1][0] - uvs[0][0], uvs[1][1] - uvs[0][1]];
var edge2 = [positions[2][axis] - positions[0][axis],
uvs[2][0] - uvs[0][0], uvs[2][1] - uvs[0][1]];
var edgeCross = vector3.normalize( vector3.cross(edge1, edge2) );
if (edgeCross[0] == 0) {
edgeCross[0] = 1;
}
tangent[axis] = -edgeCross[1] / edgeCross[0];
binormal[axis] = -edgeCross[2] / edgeCross[0];
}
// Normalize the tangent and binornmal.
var tangentLength = vector3.size(tangent);
if (tangentLength > 0.00001) {
tangent = vector3.scale(tangent, 1 / tangentLength);
}
var binormalLength = vector3.size(binormal);
if (binormalLength > 0.00001) {
binormal = vector3.scale(binormal, 1 / binormalLength);
}
// Accumulate the tangent and binormal into the tangent frame map.
for (var i = 0; i < 3; ++i) {
addTangentFrame(positions[i], normals[i], tangent, binormal);
}
}
// Add the tangent and binormal streams.
var numVertices = positionArray.numItems;
var tangents = [];
var binormals = [];
// Extract the tangent and binormal for each vertex.
for (var vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex) {
var position = this.getElement(positionArray,vertexIndex);
var normal = this.getElement(normalArray, vertexIndex);
var frame = getTangentFrame(position, normal);
// Orthonormalize the tangent with respect to the normal.
var tangent = frame[0];
tangent = vector3.sub(
tangent, vector3.scale(normal, vector3.dot(normal, tangent)));
var tangentLength = vector3.size(tangent);
if (tangentLength > 0.00001) {
tangent = vector3.scale(tangent, 1 / tangentLength);
}
// Orthonormalize the binormal with respect to the normal and the tangent.
var binormal = frame[1];
binormal = vector3.sub(
binormal, vector3.scale(tangent, vector3.dot(tangent, binormal)));
binormal = vector3.sub(
binormal, vector3.scale(normal, vector3.dot(normal, binormal)));
var binormalLength = vector3.size(binormal);
if (binormalLength > 0.00001) {
binormal = vector3.scale(binormal, 1 / binormalLength);
}
tangents.push(tangent);
binormals.push(binormal);
}
return {tangent: tangents,
binormal: binormals };
}
/**
* Create sky sphere
* @param {(int)} radius
* @param {(int)} subdivisionsHeight
* @param {(int)} subdivisionsAxis
**/
createSkySphere(radius, subdivisionsHeight, subdivisionsAxis) {
var positions = [];
var normals = [];
var texCoord = [];
var indices = [];
for (var y = 0; y <= subdivisionsHeight; y++) {
for (var x = 0; x <= subdivisionsAxis; x++) {
// Generate a vertex based on its spherical coordinates
var u = x / subdivisionsAxis;
var v = y / subdivisionsHeight;
var theta = 2 * Math.PI * u;
var phi = Math.PI * v;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi );
var ux = cosTheta * sinPhi;
var uy = cosPhi;
var uz = sinTheta * sinPhi;
positions.push(radius * ux, radius * uy, radius * uz);
normals.push(ux, uy, uz);
texCoord.push(1 - u, 1 - v);
}
}
var numVertsAround = subdivisionsAxis + 1;
for (var x = 0; x < subdivisionsAxis; x++) {
for (var y = 0; y < subdivisionsHeight; y++) {
// Make triangle 1 of quad.
indices.push(
(y + 0) * numVertsAround + x,
(y + 0) * numVertsAround + x + 1,
(y + 1) * numVertsAround + x);
// Make triangle 2 of quad.
indices.push(
(y + 1) * numVertsAround + x,
(y + 0) * numVertsAround + x + 1,
(y + 1) * numVertsAround + x + 1);
}
}
var subMesh = {};
subMesh.indices = indices;
subMesh.vertices = positions;
subMesh.textcoords = texCoord;
subMesh.normals = normals;
return subMesh;
}
/**
* get the number of vertices
* @param {(int)} width
* @param {(int)} height
**/
getVerticesCount( width, height ) {
return width * height * 3;
}
/**
* get the number of indices
* @param {(int)} width
* @param {(int)} height
**/
getIndicesCount( width, height ) {
return (width*height) + (width-1)*(height-2);
}
/**
* get vertices
* @param {(int)} width
* @param {(int)} height
**/
getVertices( width, height ) {
var vertices = [];
var i = 0;
for ( var row=0; row<height; row++ ) {
for ( var col=0; col<width; col++ ) {
vertices[i++] = col / width;
vertices[i++] = 0.0;
vertices[i++] = row / height;
}
}
return vertices;
}
/**
* get texture coordinates
* @param {(int)} width
* @param {(int)} height
**/
getTextCoord( width, height ) {
var uv = [];
var i = 0;
for ( var row=0; row<height; row++ ) {
for ( var col=0; col<width; col++ ) {
uv[i++] = col / width;
uv[i++] = row / height;
}
}
return uv;
}
/**
* get indices
* @param {(int)} width
* @param {(int)} height
**/
getIndices( width, height ) {
indices = [];
var i = 0;
for ( var row=0; row<height-1; row++ ) {
if ( (row&1)==0 ) { // even rows
for ( var col=0; col<width; col++ ) {
indices[i++] = col + row * width;
indices[i++] = col + (row+1) * width;
}
} else { // odd rows
for ( var col=width-1; col>0; col-- ) {
indices[i++] = col + (row+1) * width;
indices[i++] = col - 1 + row * width;
}
}
}
if ( (height&1) && height>2 ) {
indices[i++] = (height-1) * width;
}
return indices;
}
/**
* create plane (trianglestrip) indices
* @param {(int)} width
* @param {(int)} height
**/
createPlaneTriangleStripIndices(width, height){
var indices = new Uint32Array( getIndicesCount( width, height ) );
var i = 0;
for ( var row=0; row<height-1; row++ ) {
if ( (row&1)==0 ) { // even rows
for ( var col=0; col<width; col++ ) {
indices[i++] = col + row * width;
indices[i++] = col + (row+1) * width;
}
} else { // odd rows
for ( var col=width-1; col>0; col-- ) {
indices[i++] = col + (row+1) * width;
indices[i++] = col - 1 + + row * width;
}
}
}
return indices;
}
/**
* Create plane vertices (trianglestrip)
* @param {(int)} subdivisionsDepth
* @param {(int)} subdivisionsWidth
* @param {(int)} width
* @param {(int)} height
**/
createPlaneTriangleStripVerts(subdivisionsDepth, subdivisionsWidth, width, height) {
var vertices = new Float32Array(this.getVerticesCount( width, height ));
var i = 0;
for ( var row=0; row<height; row++ ) {
for ( var col=0; col<width; col++ ) {
vertices[i++] = col;
vertices[i++] = 0.0;
vertices[i++] = row;
}
}
return vertices;
}
/**
* Create plane texture coordinates (Trianglestrip)
* @param {(int)} subdivisionsWidth
* @param {(int)} subdivisionsDepth
**/
createPlaneTriangleStripTextCoords(subdivisionsWidth, subdivisionsDepth){
var textCoords = new Float32Array(subdivisionsWidth * subdivisionsDepth * 2);
var index = 0;
for(var y=0; y<subdivisionsDepth; y++) {
for(var x=0; x<subdivisionsWidth; x++) {
var u = x / subdivisionsWidth;
var v = y / subdivisionsDepth;
textCoords[index++] = u;
textCoords[index++] = v;
}
}
return textCoords;
}
/**
* Create cube
* @param {(int)} size
**/
createCube(size) {
var vertices = [
// Front face
-size, -size, size,
size, -size, size,
size, size, size,
-size, size, size,
// Back face
-size, -size, -size,
-size, size, -size,
size, size, -size,
size, -size, -size,
// Top face
-size, size, -size,
-size, size, size,
size, size, size,
size, size, -size,
// Bottom face
-size, -size, -size,
size, -size, -size,
size, -size, size,
-size, -size, size,
// Right face
size, -size, -size,
size, size, -size,
size, size, size,
size, -size, size,
// Left face
-size, -size, -size,
-size, -size, size,
-size, size, size,
-size, size, -size,
];
var normals = [
// Front face
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back face
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top face
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom face
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right face
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left face
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
];
var texturecoords = [
// Front face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Top face
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
// Bottom face
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
// Right face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Left face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
];
var indices = [
0, 1, 2, 0, 2, 3, // Front face
4, 5, 6, 4, 6, 7, // Back face
8, 9, 10, 8, 10, 11, // Top face
12, 13, 14, 12, 14, 15, // Bottom face
16, 17, 18, 16, 18, 19, // Right face
20, 21, 22, 20, 22, 23 // Left face
];
var currentMesh = new mesh( );
currentMesh.setViewport(this.viewport);
currentMesh.createMeshFromArrays( indices, vertices, normals, texturecoords );
return currentMesh;
}
/**
* Create cube
* @param {(int)} size
**/
createCubeFromBoundingbox( boundingbox, size ) {
console.log(boundingbox, "omg");
var maxExtend = boundingbox.maxExtent;
var minExtend = boundingbox.minExtent;
var vertices = [
// Front face
minExtend[0], minExtend[1], maxExtend[2],
maxExtend[0], minExtend[1], maxExtend[2],
maxExtend[0], maxExtend[1], maxExtend[2],
minExtend[0], maxExtend[1], maxExtend[2],
// Back face
minExtend[0], minExtend[1], minExtend[2],
minExtend[0], maxExtend[1], minExtend[2],
maxExtend[0], maxExtend[1], minExtend[2],
maxExtend[0], minExtend[1], minExtend[2],
// Top face
minExtend[0], maxExtend[1], minExtend[2],
minExtend[0], maxExtend[1], maxExtend[2],
maxExtend[0], maxExtend[1], maxExtend[2],
maxExtend[0], maxExtend[1], minExtend[2],
// Bottom face
minExtend[0], minExtend[1], minExtend[2],
maxExtend[0], minExtend[1], minExtend[2],
maxExtend[0], minExtend[1], maxExtend[2],
minExtend[0], minExtend[1], maxExtend[2],
// Right face
maxExtend[0], minExtend[1], minExtend[2],
maxExtend[0], maxExtend[1], minExtend[2],
maxExtend[0], maxExtend[1], maxExtend[2],
maxExtend[0], minExtend[1], maxExtend[2],
// Left face
minExtend[0], minExtend[1], minExtend[2],
minExtend[0], minExtend[1], maxExtend[2],
minExtend[0], maxExtend[1], maxExtend[2],
minExtend[0], maxExtend[1], minExtend[2],
];
var normals = [
// Front face
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back face
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top face
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom face
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right face
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left face
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
];
var texturecoords = [
// Front face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Top face
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
// Bottom face
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
// Right face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Left face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
];
var indices = [
0, 1, 2, 0, 2, 3, // Front face
4, 5, 6, 4, 6, 7, // Back face
8, 9, 10, 8, 10, 11, // Top face
12, 13, 14, 12, 14, 15, // Bottom face
16, 17, 18, 16, 18, 19, // Right face
20, 21, 22, 20, 22, 23 // Left face
];
var mesh = new mesh();
mesh.createMeshFromArrays( indices, vertices, normals, texturecoords );
return mesh;
}
}
export {primitives as default};

36
engine/programInfo.js Executable file
View File

@@ -0,0 +1,36 @@
/**
* Kepler - Core
*
* All rights reserved.
*
* Author: Kaj Dijksta
*
**/
/**
* Program info Object
* Object preserved to store a glsl program
*/
class programInfo{
constructor() {
this.url;
this.program;
this.pragmas;
this.librarys;
this.rawData;
this.vertexShader;
this.fragmentShader;
this.vertexShaderData;
this.fragmentShaderData;
}
}
export {programInfo as default};

2
engine/progressbar.js Executable file
View File

File diff suppressed because one or more lines are too long

97
engine/quad.js Executable file
View File

@@ -0,0 +1,97 @@
import primitives from './primitives.js';
import {math, vector3, matrix4} from './math.js';
/**
* quad this.engine.quad.draw( shader );
**/
class quad{
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
var plane = this.viewport.primitives.createPlane(2, 2, 1, 1);
console.log(plane);
this.quadView = matrix4.lookAt([0, 0, 0], [0, -1, 0], [0, 0, -1]);
this.quadProjection = matrix4.orthographic(-1, 1, -1, 1, -1, 1);
this.viewProjection = matrix4.mul(this.quadView, this.quadProjection);
this.quadVertices = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.quadVertices);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(plane.vertices), this.gl.STATIC_DRAW);
this.quadVertices.name = 'position';
this.quadVertices.itemSize = 3;
this.quadVertices.numItems = plane.vertices.length / 3;
this.quadUv = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.quadUv);
this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(plane.textureCoordinates), this.gl.STATIC_DRAW);
this.quadUv.name = 'uv';
this.quadUv.itemSize = 2;
this.quadUv.numItems = plane.textureCoordinates.length / 2;
this.quadIndices = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.quadIndices);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(plane.indices), this.gl.STATIC_DRAW);
this.quadIndices.name = 'index';
this.quadIndices.itemSize = 1;
this.quadIndices.numItems = plane.indices.length;
}
draw( shader ) {
if( !shader.compiled ) {
shader.setViewport( this.viewport );
shader.compile();
}
shader.update();
var quadVertices = this.quadVertices;
var quadIndices = this.quadIndices;
var quadUv = this.quadUv;
//console.log(quadUv);
this.gl.useProgram( shader.program );
var attribute = shader.getAttributeByName('position');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, quadVertices);
this.gl.vertexAttribPointer(attribute, quadVertices.itemSize, this.gl.FLOAT, false, 0, 0);
var attribute = shader.getAttributeByName('uv');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, quadUv);
this.gl.vertexAttribPointer(attribute, quadUv.itemSize, this.gl.FLOAT, false, 0, 0);
this.gl.bindBuffer( this.gl.ELEMENT_ARRAY_BUFFER, quadIndices );
this.gl.drawElements( this.gl.TRIANGLES, quadIndices.numItems, this.gl.UNSIGNED_SHORT, 0 );
}
}
export {quad as default};

17
engine/renderPass.js Executable file
View File

@@ -0,0 +1,17 @@
class renderPass {
constructor( ) {
this.renderToViewport;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
}
export {renderPass as default};

View File

@@ -0,0 +1,37 @@
import defaultRenderPass from '../defaultRenderPass.js';
import sampler2D from '../sampler2D.js';
import shader from '../shader.js';
class convolution extends defaultRenderPass {
prepare() {
var randomTexure = kepler.resources.getTexture("rotrandom.png");
var randomSampler = new sampler2D();
randomSampler.addTexture(randomTexure);
this.shader = new shader();
this.shader.createFromFile("shaders/convolution.shader");
this.shader.setUniform("random", randomSampler );
}
setDirection( direction ) {
if(direction == "Horizontal") {
this.shader.setUniform("imageIncrement", [1 / this.width, 0] );
} else {
this.shader.setUniform("imageIncrement", [0, 1 / this.height] );
}
}
}
export {convolution as default};

273
engine/renderPasses/deferred.js Executable file
View File

@@ -0,0 +1,273 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
class deferred {
constructor( ) {
this.realtime = true;
this.render_type = "deferred";
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
// Framebuffer
this.framebuffer = new framebuffer();
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.viewport.width;
this.framebuffer.height = this.viewport.height;
// Samplers
this.diffuseSampler = new sampler2D();
this.diffuseSampler.type = this.gl.FLOAT;
this.diffuseSampler.internalFormat = this.gl.RGBA32F;
this.normalSampler = new sampler2D();
this.normalSampler.type = this.gl.FLOAT;
this.normalSampler.internalFormat = this.gl.RGBA32F;
this.infoSampler = new sampler2D();
this.infoSampler.type = this.gl.FLOAT;
this.infoSampler.internalFormat = this.gl.RGBA32F;
this.tangentSampler = new sampler2D();
this.tangentSampler.type = this.gl.FLOAT;
this.tangentSampler.internalFormat = this.gl.RGBA32F;
// Sampler
var materialSampler = new sampler2D();
this.framebuffer.addSampler(this.diffuseSampler);
this.framebuffer.addSampler(this.normalSampler);
this.framebuffer.addSampler(this.infoSampler);
this.framebuffer.create();
}
render() {
var camera = this.viewport.mainCamera;
var viewProjection = camera.worldViewProjection;
var mode = 0;
this.gl.enableVertexAttribArray(0);
this.gl.enableVertexAttribArray(1);
this.gl.enableVertexAttribArray(2);
//this.gl.enableVertexAttribArray(3);
//this.gl.enableVertexAttribArray(4);
if(this.renderToViewport)
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, null );
else
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );
if(mode == 1) {
var sampler = this.framebuffer.samplers[0];
var texture = sampler.cubeTexture;
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.framebuffers[3]);
this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.framebuffer.renderbuffers[3]);
this.gl.texImage2D(face, 0, this.gl.RGBA, 1024, 1024, 0, this.gl.RGBA, this.gl.FLOAT, null);
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, face, texture, 0);
}
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.gl.viewport(0, 0, this.viewport.width, this.viewport.height);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.enable(this.gl.DEPTH_TEST);
this.gl.enable(this.gl.CULL_FACE);
var scene = this.viewport.scene;
var entitys = scene.getEntitys();
for(var e = 0;e<entitys.length;e++) {
var entity = entitys[e];
this.gl.disableVertexAttribArray(3);
this.gl.disableVertexAttribArray(4);
if(entity.type == "Actor") {
var mesh = entity.mesh;
var material = mesh.material;
var shader = mesh.material.shader;
shader.update( this.viewport );
if(material.alpha == 1.0) {
if(this.render_type == "deferred")
shader.setUniform("render_type", 1);
else
shader.setUniform("render_type", 0);
var world = entity.getUpdatedWorldMatrix();
shader.setUniform("viewProjection", matrix4.mul(world, viewProjection) );
shader.setUniform("world", world );
//shader.setUniform("mode", mode );
shader.setUniform("cameraPosition", this.viewport.mainCamera.eye );
shader.setUniform("worldInverseTranspose", world );
if(material.displacementMaps.length > 0)
shader.setUniform("view", this.viewport.mainCamera.view );
// note: needs a smooting out mesh->material->shader update cycle only at startup right before render loop
mesh.setViewport(this.viewport );
mesh.createBuffers( );
material.setViewport( this.viewport );
material.updateShader( );
shader.update( this.viewport );
var attribute = shader.getAttributeByName('position');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.vertexPositionBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
var attribute = shader.getAttributeByName('normal');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.vertexNormalBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
var attribute = shader.getAttributeByName('textcoord');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.textureCoordBuffer);
this.gl.vertexAttribPointer(attribute, 2, this.gl.FLOAT, false, 0, 0);
if(material.normals.length > 0) {
if(mesh.tangentBuffer) {
this.gl.enableVertexAttribArray(3);
this.gl.enableVertexAttribArray(4);
var attribute = shader.getAttributeByName('tangent');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.tangentBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
var attribute = shader.getAttributeByName('bitangent');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.binormalBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
}
}
var texureID = 0;
/*
if( material.textures.length > 0 ) {
var textureSampler = material.textures[0];
var texture = textureSampler.getTexture();
var textureUniform = shader.getUniformByName('diffuseSampler');
this.gl.activeTexture( this.gl.TEXTURE0 );
this.gl.bindTexture( this.gl.TEXTURE_2D, texture.glTexture );
this.gl.uniform1i(textureUniform, 0);
} else {
//shader.setUniform("diffuseColor", material.diffuseColor);
}
if(material.normals.length > 0) {
var textureSampler = material.normals[0];
var texture = textureSampler.getTexture();
var textureUniform = shader.getUniformByName('normalSampler');
this.gl.activeTexture( this.gl.TEXTURE0 + 1);
this.gl.bindTexture( this.gl.TEXTURE_2D, texture.glTexture );
this.gl.uniform1i(textureUniform, 1);
}
if(material.roughnessMaps.length > 0) {
var textureSampler = material.roughnessMaps[0];
var texture = textureSampler.getTexture();
if(texture) {
//console.log("texturetexture", texture);
var textureUniform = shader.getUniformByName('roughnessSampler');
this.gl.activeTexture( this.gl.TEXTURE0 + 2);
this.gl.bindTexture( this.gl.TEXTURE_2D, texture.glTexture );
this.gl.uniform1i(textureUniform, 2);
}
}
if(material.displacementMaps.length > 0) {
var textureSampler = material.displacementMaps[0];
var texture = textureSampler.getTexture();
var textureUniform = shader.getUniformByName('heightSampler');
this.gl.activeTexture( this.gl.TEXTURE0 + 3);
this.gl.bindTexture( this.gl.TEXTURE_2D, texture.glTexture );
this.gl.uniform1i(textureUniform, 3);
}
*/
this.gl.bindBuffer( this.gl.ELEMENT_ARRAY_BUFFER, mesh.vertexIndexBuffer);
this.gl.drawElements( mesh.draw_type, mesh.vertexIndexBuffer.numItems, this.gl.UNSIGNED_INT, 0 );
}
}
}
this.gl.disable(this.gl.DEPTH_TEST);
this.gl.disableVertexAttribArray(0);
this.gl.disableVertexAttribArray(1);
this.gl.disableVertexAttribArray(2);
this.gl.disableVertexAttribArray(3);
this.gl.disableVertexAttribArray(4);
}
}
export {deferred as default};

337
engine/renderPasses/depth.js Executable file
View File

@@ -0,0 +1,337 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
import material from '../material.js';
import entity from '../entity.js';
class depth {
constructor( ) {
this.lightPosition = [0, 4, 0.01];
this.degrees = 130;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.near = .635;
this.far = 400;
//
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
//depth shader
this.depthShader = new shader();
this.depthShader.definePragma("VARIANCE", (this.shadowType == "VARIANCE") ? 1 : 0 );
this.depthShader.createFromFile("shaders/depth.shader");
this.depthShader.setUniform("far", this.far );
this.depthShader.setUniform("near", this.near );
var shadowCamera = this.createShadowCam( this.lightPosition , [0, -1, 0], [0, 1, 0] );
this.shadowCameras = [];
this.shadowCameras.push( shadowCamera );
// Material
var groundMaterial = new material();
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
if(this.showFrustum) {
// Cube mesh
//var shadowCamera = this.viewport.system.createShadowCam( [0, 10, 1], [0, -1, 0], [0, 1, 0] )
var frustumMesh = this.viewport.linePrimitives.drawFrustum( shadowCamera.projection, shadowCamera.view );
frustumMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( frustumMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, 0, 0];
cubeEntity.transform.update();
this.viewport.scene.addEntity( cubeEntity );
}
}
createShadowCam( eye, target, up ) {
var width = 2048;
var height = 2048;
var shadowCamera = {};
shadowCamera.view = matrix4.lookAt( eye, target, up );
//if(this.lightType == "skyLight")
// shadowCamera.projection = matrix4.orthographic(-10, 10, -10, 10, this.near, this.far);
//if(this.lightType == "pointLight")
shadowCamera.projection = matrix4.perspective(math.degToRad(this.degrees), width / height, this.near, this.far);
console.log(shadowCamera.projection);
this.composition = matrix4.composition(shadowCamera.view, shadowCamera.projection);
this.viewProjection = matrix4.mul(shadowCamera.view, shadowCamera.projection);
shadowCamera.far = this.far;
//if( face ) {
// shadowCamera.framebuffer.target = this.gl.TEXTURE_CUBE_MAP;
// shadowCamera.framebuffer.face = face;
// shadowCamera.framebuffer.attachment = this.gl.DEPTH_ATTACHMENT;
//} else {
//shadowCamera.framebuffer.target = this.gl.TEXTURE_2D;
this.targetSampler = new sampler2D();
//this.targetSampler.type = this.gl.FLOAT;
//this.targetSampler.filter = this.gl.LINEAR;
//this.targetSampler.internalFormat = this.gl.RGBA32F;
this.targetSampler.internalformat = this.gl.RGB;
this.targetSampler.format = this.gl.RGB;
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
/*
this.ambientOcclusionFramebuffer = new framebuffer();
this.ambientOcclusionFramebuffer.width = this.width;
this.ambientOcclusionFramebuffer.height = this.height;
var ambientOcclusionSampler = new sampler2D();
ambientOcclusionSampler.type = this.gl.FLOAT;
this.ambientOcclusionFramebuffer.addSampler( ambientOcclusionSampler );
this.ambientOcclusionFramebuffer.create();
*/
//shadowCamera.filter = this.gl.LINEAR;
return shadowCamera;
}
getCamera(){
return this.shadowCameras[0];
}
render() {
console.log("render depth");
//this.gl.enableVertexAttribArray(0);
this.gl.disableVertexAttribArray(1);
this.gl.disableVertexAttribArray(2);
this.gl.disableVertexAttribArray(3);
this.gl.disableVertexAttribArray(4);
this.gl.disableVertexAttribArray(5);
//this.gl.disableVertexAttribArray(6);
//this.gl.disableVertexAttribArray(7);
var shader = this.depthShader;
//var shadowCamera = this.shadowCameras[0];
for(var c = 0; c<this.shadowCameras.length; c++) {
var shadowCamera = this.shadowCameras[c];
//var framebuffer = shadowCamera.framebuffer.glFramebuffer;
//render shadow
if(this.renderToViewport)
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, null );
else
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );
//this.gl.bindFramebuffer( this.gl.FRAMEBUFFER,null );
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.gl.viewport(0, 0, this.width, this.height);
this.gl.enable( this.gl.DEPTH_TEST );
this.gl.disable(this.gl.CULL_FACE);
//this.gl.cullFace( this.gl.FRONT );
var scene = this.viewport.scene;
var entitys = scene.getEntitys();
for(var e = 0;e<entitys.length;e++) {
var entity = entitys[e];
if(entity.type == "Actor") {
var mesh = entity.mesh;
var material = mesh.material;
//if(material.alpha == 1.0) {
var shader = this.depthShader;
var world = entity.getUpdatedWorldMatrix();
//var viewProjection = this.viewport.mainCamera.worldViewProjection;
var viewProjection = this.viewProjection;
//var camera = this.viewport.mainCamera;
//var viewProjection = camera.worldViewProjection;
shader.setUniform("viewProjection", matrix4.mul(world, viewProjection) );
shader.setUniform("world", world );
//shader.setUniform("diffuseColor", material.diffuseColor);
shader.setUniform("near", this.near);
shader.setUniform("far", this.far);
//if(material.displacementMaps.length > 0)
// shader.setUniform("view", this.viewport.mainCamera.view );
mesh.setViewport(this.viewport );
mesh.createBuffers( );
material.setViewport( this.viewport );
material.updateShader( );
shader.update( this.viewport );
//shader.update();
var attribute = shader.getAttributeByName('position');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.vertexPositionBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
if(mesh.draw_type == this.gl.TRIANGLES) {
this.gl.bindBuffer( this.gl.ELEMENT_ARRAY_BUFFER, mesh.vertexIndexBuffer);
this.gl.drawElements( mesh.draw_type, mesh.vertexIndexBuffer.numItems, this.gl.UNSIGNED_INT, 0 );
}
//}
}
}
}
//this.gl.disable(this.gl.CULL_FACE);
this.gl.cullFace( this.gl.BACK );
this.gl.enableVertexAttribArray(1);
this.gl.enableVertexAttribArray(2);
this.gl.enableVertexAttribArray(3);
this.gl.enableVertexAttribArray(4);
//this.gl.enableVertexAttribArray(5);
}
createShadows( ) {
var lightPos = [0, 15, 0];
var shadowSampler = new samplerCube(this);
shadowSampler.internalformat = this.gl.RGB;
shadowSampler.format = this.gl.RGB;
shadowSampler.type = this.gl.FLOAT;
shadowSampler.width = 1024;
shadowSampler.height = 1024;
/*
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [1, 0, 0]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_POSITIVE_X, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [-1, 0, 0]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 1, 0]), [0, 0, 1], this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, -1, 0]), [0, 0, -1], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 0, 1]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 0, -1]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, shadowSampler);
this.shadowCameras.push(shadowCamera);
*/
//this.depthShader.update();
var shadowSampler = new sampler2D();
shadowSampler.internalformat = this.gl.RGB;
shadowSampler.format = this.gl.RGB;
shadowSampler.type = this.gl.FLOAT;
shadowSampler.width = 1024;
shadowSampler.height = 1024;
//shadowSampler.bind(this.depthShader);
//this.depthShader.setUniform("far", shadowCamera.far );
/*
this.shadowShader = new shader();
this.shadowShader.createFromFile("https://community.tensorui.com/assets/shaders/shadow.shader");
this.shadowShader.setUniform("viewProjection", this.quadViewProjection );
this.shadowShader.setUniform("shadowSampler", shadowSampler );
this.shadowShader.setUniform("far", shadowCamera.far );
this.shadowShader.setUniform("lightViewProjection", shadowCamera.viewProjection );
this.shadowShader.setUniform("lightPosition", lightPos );
*/
}
}
export {depth as default};

362
engine/renderPasses/depth_old.js Executable file
View File

@@ -0,0 +1,362 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
import material from '../material.js';
import entity from '../entity.js';
class depth {
constructor( ) {
this.lightPosition = [0, 4, 0.01];
this.degrees = 130;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.near = .635;
this.far = 400;
//
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.targetSampler.internalFormat = gl.DEPTH_COMPONENT16;
this.targetSampler.format = gl.DEPTH_COMPONENT;
this.targetSampler.type = gl.UNSIGNED_SHORT;
//this.targetSampler.internalFormat = this.gl.RGBA32F;
this.framebuffer = new framebuffer();
this.framebuffer.setViewport( this.viewport );
this.framebuffer.attachment = gl.DEPTH_ATTACHMENT;
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
//depth shader
this.depthShader = new shader();
this.depthShader.definePragma("VARIANCE", (this.shadowType == "VARIANCE") ? 1 : 0 );
this.depthShader.createFromFile("shaders/depth.shader");
this.depthShader.setUniform("far", this.far );
this.depthShader.setUniform("near", this.near );
var shadowCamera = this.createShadowCam( this.lightPosition , [0, -1, 0], [0, 1, 0] );
this.shadowCameras = [];
this.shadowCameras.push( shadowCamera );
// Material
var groundMaterial = new material();
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.2;
groundMaterial.uvMultiplier = 6;
if(this.showFrustum) {
// Cube mesh
//var shadowCamera = this.viewport.system.createShadowCam( [0, 10, 1], [0, -1, 0], [0, 1, 0] )
var frustumMesh = this.viewport.linePrimitives.drawFrustum( shadowCamera.projection, shadowCamera.view );
frustumMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( frustumMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, 0, 0];
cubeEntity.transform.update();
this.viewport.scene.addEntity( cubeEntity );
}
}
createShadowCam( eye, target, up ) {
var width = 2048;
var height = 2048;
var shadowCamera = {};
shadowCamera.view = matrix4.lookAt( eye, target, up );
//if(this.lightType == "skyLight")
// shadowCamera.projection = matrix4.orthographic(-10, 10, -10, 10, this.near, this.far);
//if(this.lightType == "pointLight")
shadowCamera.projection = matrix4.perspective(math.degToRad(this.degrees), width / height, this.near, this.far);
console.log(shadowCamera.projection);
this.composition = matrix4.composition(shadowCamera.view, shadowCamera.projection);
this.viewProjection = matrix4.mul(shadowCamera.view, shadowCamera.projection);
shadowCamera.far = this.far;
//if( face ) {
// shadowCamera.framebuffer.target = this.gl.TEXTURE_CUBE_MAP;
// shadowCamera.framebuffer.face = face;
// shadowCamera.framebuffer.attachment = this.gl.DEPTH_ATTACHMENT;
//} else {
//shadowCamera.framebuffer.target = this.gl.TEXTURE_2D;
/*
this.targetSampler = new sampler2D();
//this.targetSampler.type = this.gl.FLOAT;
//this.targetSampler.filter = this.gl.LINEAR;
//this.targetSampler.internalFormat = this.gl.RGBA32F;
//this.targetSampler.internalformat = this.gl.RGB;
//this.targetSampler.format = this.gl.RGB;
this.targetSampler.type = this.gl.FLOAT;
this.targetSampler.internalFormat = this.gl.RGBA32F;
this.framebuffer = new framebuffer();
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
/*
this.ambientOcclusionFramebuffer = new framebuffer();
this.ambientOcclusionFramebuffer.width = this.width;
this.ambientOcclusionFramebuffer.height = this.height;
var ambientOcclusionSampler = new sampler2D();
ambientOcclusionSampler.type = this.gl.FLOAT;
this.ambientOcclusionFramebuffer.addSampler( ambientOcclusionSampler );
this.ambientOcclusionFramebuffer.create();
*/
//shadowCamera.filter = this.gl.LINEAR;
return shadowCamera;
}
getCamera(){
return this.shadowCameras[0];
}
render() {
console.log("render depth");
//this.gl.enableVertexAttribArray(0);
this.gl.disableVertexAttribArray(1);
this.gl.disableVertexAttribArray(2);
this.gl.disableVertexAttribArray(3);
this.gl.disableVertexAttribArray(4);
this.gl.disableVertexAttribArray(5);
//this.gl.disableVertexAttribArray(6);
//this.gl.disableVertexAttribArray(7);
var shader = this.depthShader;
//var shadowCamera = this.shadowCameras[0];
for(var c = 0; c<this.shadowCameras.length; c++) {
var shadowCamera = this.shadowCameras[c];
//var framebuffer = shadowCamera.framebuffer.glFramebuffer;
//render shadow
if(this.renderToViewport)
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, null );
else
this.gl.bindFramebuffer( this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );
//this.gl.bindFramebuffer( this.gl.FRAMEBUFFER,null );
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.gl.viewport(0, 0, this.width, this.height);
this.gl.enable( this.gl.DEPTH_TEST );
this.gl.disable(this.gl.CULL_FACE);
this.gl.cullFace( this.gl.FRONT );
var scene = this.viewport.scene;
var entitys = scene.getEntitys();
for(var e = 0;e<entitys.length;e++) {
var entity = entitys[e];
if(entity.type == "Actor") {
var mesh = entity.mesh;
var material = mesh.material;
//if(material.alpha == 1.0) {
var shader = this.depthShader;
var world = entity.getUpdatedWorldMatrix();
//var viewProjection = this.viewport.mainCamera.worldViewProjection;
var viewProjection = this.viewProjection;
//var camera = this.viewport.mainCamera;
//var viewProjection = camera.worldViewProjection;
shader.setUniform("viewProjection",viewProjection );
shader.setUniform("worldViewProjection", matrix4.mul(world, viewProjection) );
shader.setUniform("world", world );
if(entity.instancing) {
shader.setUniform("instancing", 1 );
}
//shader.setUniform("diffuseColor", material.diffuseColor);
shader.setUniform("near", this.near);
shader.setUniform("far", this.far);
//if(material.displacementMaps.length > 0)
// shader.setUniform("view", this.viewport.mainCamera.view );
mesh.setViewport(this.viewport );
mesh.createBuffers( );
material.setViewport( this.viewport );
material.updateShader( );
shader.update( this.viewport );
//shader.update();
var attribute = shader.getAttributeByName('position');
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, mesh.vertexPositionBuffer);
this.gl.vertexAttribPointer(attribute, 3, this.gl.FLOAT, false, 0, 0);
this.gl.bindBuffer( this.gl.ELEMENT_ARRAY_BUFFER, mesh.vertexIndexBuffer);
if(entity.instancing) {
this.gl.drawElementsInstanced( mesh.draw_type, mesh.vertexIndexBuffer.numItems, this.gl.UNSIGNED_INT, 0, 30 );
} else {
this.gl.drawElements( mesh.draw_type, mesh.vertexIndexBuffer.numItems, this.gl.UNSIGNED_INT, 0 );
}
//}
}
}
}
//this.gl.disable(this.gl.CULL_FACE);
this.gl.cullFace( this.gl.BACK );
this.gl.enableVertexAttribArray(1);
this.gl.enableVertexAttribArray(2);
this.gl.enableVertexAttribArray(3);
this.gl.enableVertexAttribArray(4);
//this.gl.enableVertexAttribArray(5);
}
createShadows( ) {
var lightPos = [0, 15, 0];
var shadowSampler = new samplerCube(this);
shadowSampler.internalformat = this.gl.RGB;
shadowSampler.format = this.gl.RGB;
shadowSampler.type = this.gl.FLOAT;
shadowSampler.width = 1024;
shadowSampler.height = 1024;
/*
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [1, 0, 0]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_POSITIVE_X, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [-1, 0, 0]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 1, 0]), [0, 0, 1], this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, -1, 0]), [0, 0, -1], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 0, 1]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z, shadowSampler);
this.shadowCameras.push(shadowCamera);
var shadowCamera = this.createShadowCam(lightPos, kepler.vector3.add(lightPos, [0, 0, -1]), [0, -1, 0], this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, shadowSampler);
this.shadowCameras.push(shadowCamera);
*/
//this.depthShader.update();
var shadowSampler = new sampler2D();
shadowSampler.internalformat = this.gl.RGB;
shadowSampler.format = this.gl.RGB;
shadowSampler.type = this.gl.FLOAT;
shadowSampler.width = 1024;
shadowSampler.height = 1024;
//shadowSampler.bind(this.depthShader);
//this.depthShader.setUniform("far", shadowCamera.far );
/*
this.shadowShader = new shader();
this.shadowShader.createFromFile("https://community.tensorui.com/assets/shaders/shadow.shader");
this.shadowShader.setUniform("viewProjection", this.quadViewProjection );
this.shadowShader.setUniform("shadowSampler", shadowSampler );
this.shadowShader.setUniform("far", shadowCamera.far );
this.shadowShader.setUniform("lightViewProjection", shadowCamera.viewProjection );
this.shadowShader.setUniform("lightPosition", lightPos );
*/
}
}
export {depth as default};

View File

@@ -0,0 +1,23 @@
import defaultRenderPass from '../defaultRenderPass.js';
import sampler2D from '../sampler2D.js';
import shader from '../shader.js';
class convolution extends defaultRenderPass {
prepare() {
this.blend = true;
this.shader = new shader();
this.shader.createFromFile("shaders/edgeDetection.shader");
this.shader.setUniform("res", [1 / this.viewport.width, 1 / this.viewport.height] );
}
}
export {convolution as default};

185
engine/renderPasses/fxaa.js Executable file
View File

@@ -0,0 +1,185 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
import texture from '../texture.js';
class fxaa {
constructor( ) {
this.realtime = true;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
console.log("prepare uber");
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.targetSampler.filter = this.gl.LINEAR;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.multiSample = true;
this.framebuffer.setViewport( this.viewport );
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/fxaa4.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("res", [this.width, this.height] );
this.shader.setUniform("screenSize", [this.width, this.height] );
this.shader.setUniform("inverseScreenSize", [1 /this.width, 1 /this.height] );
this.shader.setUniform("u_lumaThreshold", 0.5 );
this.shader.setUniform("u_mulReduce", 8 );
this.shader.setUniform("u_minReduce", 128 );
this.shader.setUniform("u_maxSpan", 8 );
this.shader.setUniform("u_showEdges", 0.0 );
this.shader.setUniform("u_fxaaOn", 1.0 );
this.msFB = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.msFB );
this.msRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.msRB);
const samples = 4;
const internalFormat = gl.RGBA32F;
const width = this.viewport.width;
const height = this.viewport.height;
gl.renderbufferStorageMultisample( gl.RENDERBUFFER, samples, internalFormat, width, height);
gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.msRB);
//checkFramebuffer(gl);
//gl.clearColor(1,0,0,1);
//gl.clear(gl.COLOR_BUFFER_BIT);
/*
this.texFB = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.texFB);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
const levels = 1;
gl.texStorage2D(gl.TEXTURE_2D, levels, internalFormat, width, height);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
*/
}
render() {
//this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, this.fxaaFramebuffer.msaaFramebuffer );
//this.gl.bindFramebuffer(this.gl.DRAW_FRAMEBUFFER, this.fxaaFramebuffer.glFramebuffer );
//this.gl.blitFramebuffer(0, 0, this.width, this.height,
// 0, 0, this.width, this.height,
// this.gl.COLOR_BUFFER_BIT, this.gl.LINEAR);
/*
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
*/
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
// this.msaaFramebuffer //Framebuffer
// this.msaaColorRenderBuffer //Renderbuffer
// this.msaaDepthRenderBuffer //Renderbuffer
//console.log(this.framebuffer.glFramebuffer);
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
//this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.framebuffer.msaaColorRenderBuffer);
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.msaaFramebuffer);
//if(this.renderToViewport)
// this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null );
//else
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.msFB );//msaaFramebuffer
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null );
//this.gl.bindRenderbuffer(this.gl.FRAMEBUFFER, this.msRB );
//this.shader.setUniform("cameraPosition", camera.eye );
this.shader.update(this.viewport);
this.gl.viewport(0, 0, this.viewport.width, this.viewport.height);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear( this.gl.COLOR_BUFFER_BIT );//this.gl.clear( this.gl.DEPTH_BUFFER_BIT );
this.gl.disable(this.gl.DEPTH_TEST);
this.viewport.quad.draw( this.shader, null );
/*
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.msFB);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.framebuffer.glFramebuffer);
gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 1.0]);
gl.blitFramebuffer(
0, 0, this.width, this.height,
0, 0, this.width, this.height,
gl.COLOR_BUFFER_BIT, gl.LINEAR);
*/
/*
this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, this.framebuffer.msaaFramebuffer);
//this.gl.bindFramebuffer(this.gl.DRAW_FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.clearBufferfv(this.gl.COLOR, 0, [0.0, 0.0, 0.0, 1.0]);
this.gl.blitFramebuffer(
0, 0, this.width, this.height,
0, 0, this.width, this.height,
this.gl.COLOR_BUFFER_BIT, this.gl.NEAREST
);
this.gl.bindFramebuffer(this.gl.READ_FRAMEBUFFER, this.msaaFramebuffer );
this.gl.bindFramebuffer(this.gl.DRAW_FRAMEBUFFER, this.glFramebuffer );
this.gl.blitFramebuffer(0, 0, this.width, this.height,
0, 0, this.width, this.height,
this.gl.COLOR_BUFFER_BIT, this.gl.LINEAR);//this.gl.LINEAR
*/
}
}
export {fxaa as default};

62
engine/renderPasses/hdr.js Executable file
View File

@@ -0,0 +1,62 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class hdr {
constructor( ) {
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.gl = this.engine.gl;
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/hdr.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("screenSize", [this.width, this.height] );
}
render() {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.shader.update();
this.viewport.quad.draw( this.shader, null );
}
}
export {hdr as default};

View File

@@ -0,0 +1,62 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class highpassFilter {
constructor( ) {
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.gl = this.engine.gl;
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/highpass.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("screenSize", [this.width, this.height] );
}
render() {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.shader.update();
this.viewport.quad.draw( this.shader, null );
}
}
export {highpassFilter as default};

View File

@@ -0,0 +1,67 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class fxaa {
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/template.shader");
this.shader.setUniform("viewProjection", this.viewport.quadViewProjection );
this.shader.setUniform("screenSize", [this.width, this.height] );
}
render() {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.shader.update();
this.viewport.quad.draw( this.shader, null );
}
}
export {fxaa as default};

31
engine/renderPasses/shadow.js Executable file
View File

@@ -0,0 +1,31 @@
import defaultRenderPass from '../defaultRenderPass.js';
import sampler2D from '../sampler2D.js';
import shader from '../shader.js';
class shadow extends defaultRenderPass {
prepare() {
var randomTexure = kepler.resources.getTexture("rotrandom.png");
var randomSampler = new sampler2D();
randomSampler.addTexture(randomTexure);
var depthPasses = this.viewport.system.depthPasses;
var depthpass = depthPasses[0];
this.shader = new shader();
this.shader.createFromFile("shaders/shadow.shader");
this.shader.setUniform("bias", 0.36 );
this.shader.setUniform("minVariance", 0.0001 );
this.shader.setUniform("shadowNoiseSampler", randomSampler );
this.shader.setUniform("lightPosition", depthpass.lightPosition );
this.shader.setUniform("shadowDepthSampler", depthpass.framebuffer.getSampler() );
this.shader.setUniform("lightViewProjection", depthpass.viewProjection );
}
}
export {shadow as default};

67
engine/renderPasses/sobel.js Executable file
View File

@@ -0,0 +1,67 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class fxaa {
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/template.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("screenSize", [this.width, this.height] );
}
render() {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.shader.update();
this.viewport.quad.draw( this.shader, null );
}
}
export {fxaa as default};

155
engine/renderPasses/ssao.js Executable file
View File

@@ -0,0 +1,155 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class ssao {
constructor( ) {
this.realtime = true;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.framebuffer = new framebuffer();
this.framebuffer.width = this.viewport.width;
this.framebuffer.height = this.viewport.height;
var ambientOcclusionSampler = new sampler2D();
ambientOcclusionSampler.type = this.gl.FLOAT;
this.framebuffer.setViewport( this.viewport );
this.framebuffer.addSampler( ambientOcclusionSampler );
this.framebuffer.create();
var randomImage2 = new Uint8Array ( [149,123,253,255, 126,3,96,255, 164,246,98,255, 154,177,13,255,
52,83,220,255, 1,142,142,255, 32,57,79,255, 48,159,32,255,
56,232,114,255, 177,216,203,255, 69,196,217,255, 240,165,81,255,
224,56,85,255, 232,89,189,255, 143,25,202,255, 117,73,12,255] );
var diffuseTexture = kepler.textureFromTypedArray( randomImage2, 4, 4 );
var randomSampler = new sampler2D();
randomSampler.texture = diffuseTexture;
this.shader = new shader();
this.shader.createFromFile("shaders/ambientOcclusion.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("screenWidth", this.viewport.width );
this.shader.setUniform("screenHeight", this.viewport.height );
this.shader.setUniform("far", this.viewport.mainCamera.far );
this.shader.setUniform("randomSampler", randomSampler);
var radius = 0.1;
var scale = [ vector3.scale( new vector3(-0.556641,-0.037109,-0.654297), radius ),
vector3.scale( new vector3(0.173828,0.111328,0.064453), radius ),
vector3.scale( new vector3(0.001953,0.082031,-0.060547), radius ),
vector3.scale( new vector3(0.220703,-0.359375,-0.062500), radius ),
vector3.scale( new vector3(0.242188,0.126953,-0.250000), radius ),
vector3.scale( new vector3(0.070313,-0.025391,0.148438), radius ),
vector3.scale( new vector3(-0.078125,0.013672,-0.314453), radius ),
vector3.scale( new vector3(0.117188,-0.140625,-0.199219), radius ),
vector3.scale( new vector3(-0.251953,-0.558594,0.082031), radius ),
vector3.scale( new vector3(0.308594,0.193359,0.324219), radius ),
vector3.scale( new vector3(0.173828,-0.140625,0.031250), radius ),
vector3.scale( new vector3(0.179688,-0.044922,0.046875), radius ),
vector3.scale( new vector3(-0.146484,-0.201172,-0.029297), radius ),
vector3.scale( new vector3(-0.300781,0.234375,0.539063), radius ),
vector3.scale( new vector3(0.228516,0.154297,-0.119141), radius ),
vector3.scale( new vector3(-0.119141,-0.003906,-0.066406), radius ),
vector3.scale( new vector3(-0.218750,0.214844,-0.250000), radius ),
vector3.scale( new vector3(0.113281,-0.091797,0.212891), radius ),
vector3.scale( new vector3(0.105469,-0.039063,-0.019531), radius ),
vector3.scale( new vector3(-0.705078,-0.060547,0.023438), radius ),
vector3.scale( new vector3(0.021484,0.326172,0.115234), radius ),
vector3.scale( new vector3(0.353516,0.208984,-0.294922), radius ),
vector3.scale( new vector3(-0.029297,-0.259766,0.089844), radius ),
vector3.scale( new vector3(-0.240234,0.146484,-0.068359), radius ),
vector3.scale( new vector3(-0.296875,0.410156,-0.291016), radius ),
vector3.scale( new vector3(0.078125,0.113281,-0.126953), radius ),
vector3.scale( new vector3(-0.152344,-0.019531,0.142578), radius ),
vector3.scale( new vector3(-0.214844,-0.175781,0.191406), radius ),
vector3.scale( new vector3(0.134766,0.414063,-0.707031), radius ),
vector3.scale( new vector3(0.291016,-0.833984,-0.183594), radius ),
vector3.scale( new vector3(-0.058594,-0.111328,0.457031), radius ),
vector3.scale( new vector3(-0.115234,-0.287109,-0.259766), radius ) ];
var kernelRad = [[1.163003/radius,4.624262/radius,9.806342/radius,2.345541/radius],
[2.699039/radius,6.016871/radius,3.083554/radius,3.696197/radius],
[1.617461/radius,2.050939/radius,4.429457/radius,5.234036/radius],
[3.990876/radius,1.514475/radius,3.329241/radius,7.328508/radius],
[2.527725/radius,3.875453/radius,8.760140/radius,1.412308/radius],
[2.885205/radius,1.977866/radius,3.617674/radius,3.453552/radius],
[1.712336/radius,5.341163/radius,4.771728/radius,2.965737/radius],
[1.204293/radius,1.108428/radius,2.109570/radius,2.475453/radius] ];
//this.shader.setUniform("scale", scale );
//this.shader.setUniform("kernelRad", kernelRad );
//this.shader.setUniform("kernel", scale );
//this.shader.setUniform("kernelRad", kernelRad );
this.shader.setUniform("far", this.viewport.mainCamera.far );
console.log("this.viewport.mainCamera.far", this.viewport.mainCamera.far);
//this.shader.setUniform("positionSampler", this.infoSampler );
//this.shader.setUniform("positionSampler", this.infoSampler );
// ssaoConvolutionFinalSampler );
var ssaoKernel = [];
for (var i = 0; i < 64; ++i)
{
var sample = [
Math.random() * 2.0 - 1.0,
Math.random() * 2.0 - 1.0,
Math.random()
];
sample = vector3.normalize(sample);
sample *= Math.random();
scale = i / 64.0;
ssaoKernel.push(sample);
}
this.shader.setUniform("samples", ssaoKernel );
this.shader.setUniform("parameters", [0.6, 0.075, 1.0, 1.0] );
}
render() {
if(this.renderToViewport)
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null );
else
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.viewport(0, 0, this.viewport.width, this.viewport.height);
this.viewport.quad.draw( this.shader, null );
}
}
export {ssao as default};

63
engine/renderPasses/template.js Executable file
View File

@@ -0,0 +1,63 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class template {
constructor( ) {
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D( );
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer( );
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/template.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
}
render() {
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.viewport.quad.draw( this.shader );
}
}
export {template as default};

20
engine/renderPasses/tonemap.js Executable file
View File

@@ -0,0 +1,20 @@
import defaultRenderPass from '../defaultRenderPass.js';
import sampler2D from '../sampler2D.js';
import shader from '../shader.js';
class tonemap extends defaultRenderPass {
prepare() {
this.shader = new shader();
this.shader.createFromFile("shaders/tonemap.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
}
}
export {tonemap as default};

227
engine/renderPasses/uber.js Executable file
View File

@@ -0,0 +1,227 @@
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class uber {
constructor( ) {
this.realtime = true;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
console.log("prepare uber");
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D();
this.targetSampler.type = this.gl.FLOAT;
this.targetSampler.filter = this.gl.LINEAR;
this.framebuffer = new framebuffer();
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.setViewport( this.viewport );
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
var shadowNoiseTexure = kepler.resources.getTexture("rotrandom.png");
var shadowNoiseSampler = new sampler2D();
shadowNoiseSampler.addTexture(shadowNoiseTexure);
var sphericalHarmonics = [];
for(var c = 0; c<8; c++) {
sphericalHarmonics.push([Math.random, Math.random, Math.random]);
}
//this.reflectionSampler = new samplerCube();
//this.reflectionSampler.addTexture(kepler.resources.getTexture("positive_x"), this.gl.TEXTURE_CUBE_MAP_POSITIVE_X);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("negative_x"), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("negative_y"), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("positive_y"), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("positive_z"), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("negative_z"), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
///this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
//this.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
this.reflectionSampler = this.viewport.system.reflectionSampler;
//deferredSampler.internalFormat = this.gl.RGBA8;
//deferredSampler.filter = this.gl.UNSIGNED_BYTE
this.shader = new shader();
this.shader.createFromFile( "shaders/deferred.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
this.shader.setUniform("reflectionSampler", this.reflectionSampler );
//this.shader.setUniform("materialSampler", materialSampler );
//this.shader.setUniform("shadowDepthSampler", this.viewport.shadowCameras[0].sampler );
this.shader.setUniform("shadowNoiseSampler", shadowNoiseSampler );
this.shader.setUniform("shadowBias", .6 );//0.03
var depthPasses = this.viewport.system.depthPasses;
var depthpass = depthPasses[0];
this.shader.setUniform("lightPosition", depthpass.lightPosition );
this.shader.setUniform("lightType", depthpass.lightType == "pointLight" ? 0 : 1 );
this.shader.setUniform("SpotAngles", [30, 0.1]);
this.shader.setUniform("LightColor", [1, 1, 1] );
this.shader.setUniform("far", this.viewport.mainCamera.far );
this.shader.setUniform("shadowFar", this.viewport.mainCamera.far );
this.shader.setUniform("anisotropy", 0.1 );
this.shader.setUniform("lightGeometry", [1.0 / 145.0, 4.0, 0.1] );
this.shader.setUniform("clearCoatColor", [1.0, 1.0, 1.0] );
this.shader.setUniform("lightColor", [1,1,1] ); //colorTemperatureToSRGB(6000.0) );
this.shader.setUniform("lightDirection", [0.0, -0.7, 0.5] );
this.shader.setUniform("luma_z", 1 );
//this.shader.setUniform("lightPosition", [0, 12, 12] );
this.shader.setUniform("lightIntensity", .81);
this.shader.setUniform("environmentLuminance", 0.6);
//this.shader.setUniform("lightIntensity", 1.3);
//this.shader.setUniform("environmentLuminance", 0.35);
this.shader.setUniform("roughness", 1. );
this.shader.setUniform("clearCoatRoughness", .2 );
this.shader.setUniform("clearCoat", 0.3 );
this.shader.setUniform("clearCoatThickness", 0.2 );
this.shader.setUniform("metallic", .0 );
this.shader.setUniform("reflectance", 0.1);
this.shader.setUniform("reflectance", 0.0);
this.shader.setUniform("sphericalHarmonics", sphericalHarmonics );
this.shader.setUniform("attenuation", 3 );
}
toViewport( yeas ) {
this.renderToViewport = yeas;
this.shader.setUniform("luma_z", this.renderToViewport ? 0 : 1 );
}
colorTemperatureToSRGB(T) {
// Compute CCT in CIE 1960 space
var u = (0.860117757 + 1.54118254e-4 * T + 1.28641212e-7 * T * T) /
(1 + 8.42420235e-4 * T + 7.08145163e-7 * T * T);
var v = (0.317398726 + 4.22806245e-5 * T + 4.20481691e-8 * T * T) /
(1 - 2.89741816e-5 * T + 1.61456053e-7 * T * T);
// Convert to xyY
var x = (3.0 * u) / (2.0 * u - 8.0 * v + 4.0);
var y = (2.0 * v) / (2.0 * u - 8.0 * v + 4.0);
// Convert to XYZ
var XYZ = [x / y, 1.0, (1.0 - x - y) / y];
// Convert to linear sRGB
var rgb = [
XYZ[0] * 3.2406 + XYZ[1] * -1.5372 + XYZ[2] * -0.4986,
XYZ[0] * -0.9689 + XYZ[1] * 1.8758 + XYZ[2] * 0.0415,
XYZ[0] * 0.0557 + XYZ[1] * -0.2040 + XYZ[2] * 1.0570
];
var max = Math.max(rgb[0], Math.max(rgb[1], rgb[2]));
rgb[0] /= max;
rgb[1] /= max;
rgb[2] /= max;
return rgb;
}
render() {
//console.log("render uber");
var camera = this.viewport.mainCamera;
var scene = this.viewport.scene;
var entitys = scene.getEntitys();
var deferredShader = this.shader;
if(this.renderToViewport)
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null );
else
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer );//msaaFramebuffer
deferredShader.setUniform("cameraPosition", camera.eye );
deferredShader.update(this.viewport);
this.gl.viewport(0, 0, this.viewport.width, this.viewport.height);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear( this.gl.DEPTH_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT );//this.gl.clear( this.gl.DEPTH_BUFFER_BIT );
this.gl.enable( this.gl.DEPTH_TEST );
this.gl.enable( this.gl.CULL_FACE );
//this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
//this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
//nnee
//this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);//nnee
//this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
//var lights = 0;
//this.gl.disable(this.gl.DEPTH_TEST);
//this.gl.enable(this.gl.BLEND);
//this.gl.enable(this.gl.DEPTH_TEST);
//this.gl.enable(this.gl.BLEND);
//this.gl.blendEquation(this.gl.FUNC_ADD);
//this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
//deferredShader.setUniform("lightViewProjection", this.viewport.shadowCameras[0].viewProjection );
//this.shader.setUniform("lightPosition", [1,1999, 1000], true );
var depthPasses = this.viewport.system.depthPasses;
this.viewport.quad.draw( deferredShader, null );
//for(var e = 0;e<depthPasses.length;e++) {
//this.gl.clear( this.gl.DEPTH_BUFFER_BIT);
//var depthPass = depthPasses[e];
//this.shader.setUniform("lightPosition", depthPass.lightPosition, true );
//}
}
}
export {uber as default};

73
engine/renderPipeline.js Executable file
View File

@@ -0,0 +1,73 @@
/**
* quad this.engine.quad.draw( shader );
**/
class renderPipeline {
constructor( viewport ) {
this.viewport = viewport;
this.renderPasses = [];
}
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
}
/**
* Add renderpass
* @param {(renderpass)} renderpass
**/
addRenderpass( renderPass, name ){
renderPass.setViewport( this.viewport );
if(name) {
renderPass.name = name;
}
renderPass.prepare();
if(renderPass.isDefault) {
renderPass.prepareDefault();
}
this.renderPasses.push( renderPass );
}
getRenderpass( name ){
for(var c = 0; c < this.renderPasses.length; c++) {
var renderpass = this.renderPasses[c];
if(renderpass.name == name) {
return renderpass;
}
}
}
getRenderPasses(){
return this.renderPasses;
}
}
export {renderPipeline as default};

369
engine/renderSystem.js Executable file
View File

@@ -0,0 +1,369 @@
/*
* Copyright 2012-2019, kaj dijkstra Inc,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import keplerEngine from './kepler.js';
import scene from './scene.js';
import primitives from './primitives.js';
import samplerCube from './samplerCube.js';
import sampler2D from './sampler2D.js';
import shader from './shader.js';
import framebuffer from './framebuffer.js';
import {math, vector3, matrix4} from './math.js';
import renderPipeline from './renderPipeline.js';
// import render passes
import deferred from './renderPasses/deferred.js';
import uber from './renderPasses/uber.js';
import ssao from './renderPasses/ssao.js';
import convolution from './renderPasses/convolution.js';
import fxaa from './renderPasses/fxaa.js';
import highpassFilter from './renderPasses/highpassFilter.js';
import hdr from './renderPasses/hdr.js';
import depth from './renderPasses/depth.js';
import shadow from './renderPasses/shadow.js';
import tonemap from './renderPasses/tonemap.js';
/**
* Rendersystem
**/
class renderSystem{
constructor( ) {
this.scene = new scene();
this.render_type = "forward"; // "Forward" or "Deferred"
this.viewMode = 0;
this.depthPasses = [];
}
setRenderMode( mode ) { // "deferred", "forward"
this.render_type = mode;
}
setViewMode( mode ) { "lit", "unlit", "lighting Only", "Reflections",
this.viewMode = mode;
var uberPass = this.deferredRenderPipeline.getRenderpass("uber");
uberPass.shader.setUniform("viewMode", mode );
}
setViewport( viewPort ){
this.viewPort = viewPort;
this.gl = viewPort.gl;
this.forwardRenderPipeline = new renderPipeline( this.viewPort );
this.deferredRenderPipeline = new renderPipeline( this.viewPort );
}
createRenderPasses(){
//this.createCubemapSampler();
// create render passes
var deferredPass = new deferred();
var uberPass = new uber();
var ssaoPass = new ssao();
var ssaoConvolutionXPass = new convolution();
var ssaoConvolutionYPass = new convolution();
var fxaaPass = new fxaa();
var highpassFilterPass = new highpassFilter();
var bloomConvolutionXPass = new convolution();
var bloomConvolutionYPass = new convolution();
var hdrPass = new hdr();
var shadowPass = new shadow();
var tonemapPass = new tonemap();
var forwardRenderPass = new deferred();
deferredPass.render_type = "deferred";
forwardRenderPass.render_type = "forward";
// Add lights
var lightEntitys = this.viewPort.scene.getLights();
for(var c = 0; c<lightEntitys.length; c++) {
var lightEntity = lightEntitys[c];
var depthPass = new depth();
// Light properties
depthPass.lightPosition = lightEntity.transform.position;
depthPass.lightType = lightEntity.type;
depthPass.showFrustum = lightEntity.showFrustum;
depthPass.realtime = false;
if(lightEntity.degrees)
depthPass.degrees = lightEntity.degrees;
//depthPass.renderToViewport = true;
this.deferredRenderPipeline.addRenderpass( depthPass, "depth" );
this.forwardRenderPipeline.addRenderpass( depthPass, "depth" );
this.depthPasses.push(depthPass);
}
console.log('lightEntity', lightEntity);
// Add them to the render system in the right order
// Deferred pipeline
this.deferredRenderPipeline.addRenderpass( deferredPass, "deferred" );
this.deferredRenderPipeline.addRenderpass( ssaoPass, "ssao" );
this.deferredRenderPipeline.addRenderpass( shadowPass, "shadowmap" );
this.deferredRenderPipeline.addRenderpass( ssaoConvolutionXPass, "ssaoConvolutionX" );
this.deferredRenderPipeline.addRenderpass( ssaoConvolutionYPass, "ssaoConvolutionY" );
this.deferredRenderPipeline.addRenderpass( uberPass, "uber" );
//this.deferredRenderPipeline.addRenderpass( highpassFilterPass, "highpassFilter" );
//this.deferredRenderPipeline.addRenderpass( bloomConvolutionXPass, "bloomConvolutionX" );
//this.deferredRenderPipeline.addRenderpass( bloomConvolutionYPass, "bloomConvolutionY" );
//this.deferredRenderPipeline.addRenderpass( hdrPass, "hdr" );
this.deferredRenderPipeline.addRenderpass( fxaaPass, "fxaa" );
//this.deferredRenderPipeline.addRenderpass( tonemapPass, "tonemap" );
// Forward pipeline
this.forwardRenderPipeline.addRenderpass( forwardRenderPass, "forward" );
//shadowPass.renderToViewport = true;
forwardRenderPass.renderToViewport = true;
fxaaPass.renderToViewport = true;
//depthPass.renderToViewport = true;
//ssaoConvolutionYPass.renderToViewport = true;
//uberPass.renderToViewport = true;
// Set convolution Directions
ssaoConvolutionXPass.setDirection("Horizontal");
ssaoConvolutionYPass.setDirection("Vertical");
// Route all the renderpasses
ssaoPass.shader.setUniform("infoSampler", deferredPass.normalSampler);
ssaoConvolutionXPass.shader.setUniform("image", shadowPass.framebuffer.getSampler() );
ssaoConvolutionYPass.shader.setUniform("image", ssaoConvolutionXPass.framebuffer.getSampler() );
uberPass.shader.setUniform("diffuseSampler", deferredPass.diffuseSampler);
uberPass.shader.setUniform("normalSampler", deferredPass.normalSampler);
uberPass.shader.setUniform("infoSampler", deferredPass.infoSampler);
uberPass.shader.setUniform("ambientOcclusionSampler", ssaoConvolutionYPass.framebuffer.getSampler() );
shadowPass.shader.setUniform("positionSampler", deferredPass.infoSampler );
shadowPass.shader.setUniform("ambientOcclusionSampler", ssaoPass.framebuffer.getSampler() );
//tonemapPass.shader.setUniform("colorSampler", uberPass.aaSampler );
//uberPass.shader.setUniform("shadowDepthSampler", depthPass.framebuffer.getSampler() );
//uberPass.shader.setUniform("lightViewProjection", depthPass.viewProjection );
fxaaPass.shader.setUniform("deferredSampler", uberPass.framebuffer.getSampler() );
//tonemapPass.shader.setUniform("colorSampler", fxaaPass.framebuffer.getSampler() );
for(var c = 0; c<this.depthPasses.length; c++) {
var depthpass = this.depthPasses[c];
uberPass.shader.setUniform("shadowDepthSampler", depthPass.framebuffer.getSampler() );
uberPass.shader.setUniform("lightViewProjection", depthPass.viewProjection );
}
}
render( ) {
if(this.render_type == "deferred") {
var renderPasses = this.deferredRenderPipeline.getRenderPasses();
} else {
var renderPasses = this.forwardRenderPipeline.getRenderPasses();
}
for(var c = 0; c < renderPasses.length; c++) {
var renderpass = renderPasses[c];
if(renderpass.realtime) {
renderpass.render();
} else if( !renderpass.updated ){
renderpass.render();
renderpass.updated = true;
}
if(renderpass.renderToViewport) {
return true;
}
}
this.gl.flush();
}
createShadowCam( eye, target, up ) {
var width = 2048;
var height = 2048;
var width = 50;
var height = width;
var near = .0001;
var far = 30;
var shadowCamera = {};
shadowCamera.view = matrix4.lookAt( eye, target, up );
//shadowCamera.projection = matrix4.orthographic(-width, width, -height, height, -near, far);
shadowCamera.projection = matrix4.perspective(math.degToRad(55), width / height, near, far);
shadowCamera.viewProjection = matrix4.mul(shadowCamera.view, shadowCamera.projection);
shadowCamera.far = far;
return shadowCamera;
}
/**
* initialize webgl
* @param {(Dom canvas)} canvas
**/
initializeWebgl( canvas ) {
//try {
var width = canvas.offsetWidth;
var height = canvas.offsetHeight;
canvas.width = math.nextHighestPowerOfTwo(width);
canvas.height = math.nextHighestPowerOfTwo(height);
console.log('adjusted resolution to width:', canvas.width , 'height', canvas.height);
this.canvas = canvas;
//this.setLoadingText("Init Webgl");
if(this.render_type == "forward")
this.gl = canvas.getContext("webgl2");
else
this.gl = canvas.getContext("webgl2"); //, { antialias: false }
//, { antialias: false }canvas.getContext("experimental-webgl", {alpha: false});
gl = this.gl;
this.extensions = {};
this.extensions.EXT_shader_texture_lod = this.gl.getExtension('EXT_shader_texture_lod');
this.extensions.textureFloat = this.gl.getExtension('OES_texture_float');
this.extensions.textureFloat = this.gl.getExtension('OES_texture_float');
this.extensions.textureHalf = this.gl.getExtension('OES_texture_half_float');
this.extensions.elementIndexUint = this.gl.getExtension('OES_element_index_uint');
this.extensions.derivatives = this.gl.getExtension('OES_standard_derivatives');
this.extensions.texture3d = this.gl.getExtension("OES_texture_3D");
this.extensions.depthTexture = this.gl.getExtension("WEBKIT_WEBGL_depth_texture");
this.extensions.anisotropic = this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
this.extensions.textureCompression = this.gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc");
this.extensions.OES_half_float_linear = this.gl.getExtension("OES_half_float_linear");
this.extensions.WEBGL_draw_buffers = this.gl.getExtension("WEBGL_draw_buffers");
this.extensions.WEBGL_color_buffer_float = this.gl.getExtension("WEBGL_color_buffer_float");
this.extensions.EXT_sRGB = this.gl.getExtension("EXT_sRGB");
this.extensions.EXT_color_buffer_float = this.gl.getExtension("EXT_color_buffer_float");
this.extensions.OES_texture_float_linear = this.gl.getExtension("OES_texture_float_linear");
//this.setLoadingText("Init Kepler");
if(this.extensions.elementIndexUint)
this.indexType = this.gl.UNSIGNED_INT;
else
this.indexType = this.gl.UNSIGNED_SHORT;
var formats = this.gl.getParameter(this.gl.COMPRESSED_TEXTURE_FORMATS);
this.extensions.dxt5Supported = false;
for(var i = 0; i<formats.length; i++) {
if(formats[i] == this.extensions.textureCompression.COMPRESSED_RGBA_S3TC_DXT5_EXT) {
this.extensions.dxt5Supported = true;
}
}
console.log(this.extensions, formats);
this.gl.viewportWidth = canvas.width;
this.gl.viewportHeight = canvas.height;
this.width = canvas.width;
this.height = canvas.height;
this.canvas = canvas;
//return this.gl;
//} catch (e) { }
//if (!this.gl) {
// alert("Could not initialise WebGL, sorry :-(");
//}
console.log(this.gl);
return this.gl;
}
/**
* set graphics library
* @param {(string)} name
**/
setGraphicsLibrary(name) {
/*
*/
}
}
export {renderSystem as default};

738
engine/resourceManager.js Executable file
View File

File diff suppressed because one or more lines are too long

190
engine/sampler2D.js Executable file
View File

@@ -0,0 +1,190 @@
/*
* Copyright 2013-2019, kaj dijkstra,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import texture from './texture.js';
import {math} from './math.js';
/**
* Sampler2D
**/
class sampler2D{
constructor( ){
this.texture;
this.id = ++kepler.samplerId;
this.alpha = 1.0;
this.binded = false;
this.anisotropic = false;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
this.FLIP_Y = true;
this.filter = this.gl.NEAREST;
this.filter = this.gl.LINEAR;
this.MIN_FILTER = this.gl.LINEAR;
this.MAG_FILTER = this.gl.LINEAR;
this.WRAP_S = this.gl.REPEAT;
this.WRAP_T = this.gl.REPEAT;
this.datatype = this.gl.RGBA;
this.format = this.gl.RGBA;
this.internalFormat = this.gl.RGBA;
this.target = this.gl.TEXTURE_2D;
this.type = this.gl.FLOAT;
}
setTarget( viewport ) {
var textureObject = new texture();
textureObject.setViewport( viewport );
this.addTexture( textureObject );
}
getTexture( face ) {
return this.texture;
}
getTextures( ) {
return [this.texture];
}
addTexture( textureObject ) {
this.texture = textureObject;
}
setType(type) {
//this.texture.type = "type";
}
/**
* bind sampler to shader
* @param {(shader)} shader
**/
bind(shader) {
var txt = this.texture;
var data = this.texture.data;
var type = txt.dataType;
var gl = this.gl;
//this.type = type;
if (type == "framebuffer" ) {
this.texture.glTexture = this.texture.data;
type = txt.type;
} else {
var mips = [];
var width = txt.width;
var height = txt.height;
//if(!this.binded)
this.id = 1 + shader.samplerId++;
gl.activeTexture(gl.TEXTURE0 + this.id);
gl.enable ( this.gl.BLEND ) ;
gl.bindTexture(gl.TEXTURE_2D, txt.glTexture );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.FLIP_Y);
//serialize txt data type
switch( type ) {
case "float":
this.type = this.gl.FLOAT;
gl.texImage2D(gl.TEXTURE_2D, 0, kepler.extensions.EXT_sRGB , width, height, 0, this.internalFormat, this.type, data);
break;
case "int":
this.type = this.gl.UNSIGNED_BYTE;
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.internalFormat, this.type, data);
break;
case "depth":
gl.texImage2D(gl.TEXTURE_2D, 0, this.gl.DEPTH_COMPONENT, width, height, 0, this.gl.DEPTH_COMPONENT, this.gl.UNSIGNED_SHORT, null);
break;
case "image":
this.type = this.gl.UNSIGNED_BYTE;
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.internalFormat,this.type, data);
break;
case "canvas":
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.internalFormat, this.UNSIGNED_BYTE, data);
break;
case "COMPRESSED_RGBA":
//var textureCompression = kepler.extensions.textureCompression;
var mipmaps = txt.mipmaps;
var width = mipmaps[0].width;
var height = mipmaps[0].height;
for(var i = 0; i < mipmaps.length; i++) {
var mipmap = mipmaps[i];
gl.compressedTexImage2D(gl.TEXTURE_2D, i, mipmap.internalFormat, mipmap.width, mipmap.height, 0, mipmap.byteArray);
}
break;
}
if(this.anisotropic) {
//var extension = kepler.extensions.anisotropic;
//gl.texParameteri( this.gl.TEXTURE_2D, extension.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic );
}
if (math.isPowerOfTwo(width) && math.isPowerOfTwo(height) ) {
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);// mipmaps > 1 ? this.gl.LINEAR_MIPMAP_LINEAR : this.gl.LINEAR
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.WRAP_S);
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.WRAP_T);
if(this.type != this.gl.FLOAT)
gl.generateMipmap(gl.TEXTURE_2D);
} else {
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
gl.bindTexture(gl.TEXTURE_2D, null);
this.binded = true;
}
}
}
export {sampler2D as default};

223
engine/samplerCube.js Executable file
View File

@@ -0,0 +1,223 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
var cubeSamplerID = 0;
import {math} from './math.js';
/**
* light
**/
class samplerCube{
constructor() {
this.textures = [];
this.cubeTexture = gl.createTexture();
this.id = ++kepler.samplerId;//+engine.samplerCubeID
this.FLIP_Y = true;
this.MIN_FILTER = gl.LINEAR;
this.MAG_FILTER = gl.LINEAR;
this.WRAP_S = gl.REPEAT;
this.WRAP_T = gl.REPEAT;
this.datatype = gl.RGB;
this.format = gl.RGB;
this.internalFormat = gl.RGB;
this.target = gl.TEXTURE_CUBE_MAP;
this.type = gl.UNSIGNED_BYTE;
this.alpha = 1.0;
this.binded = false;
this.anisotropic = false;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
setTarget(target) {
var faces = [ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
gl.TEXTURE_CUBE_MAP_NEGATIVE_Z ];
for(var c =0; c<faces.length; c++) {
var texture = new texture();
texture.face = faces[c];
this.addTexture( texture );
}
}
getTexture( face ) {
if( face ) {
for(var c = 0; c < this.textures.length; c++) {
if( face == this.textures[c].face ) {
return this.textures[c];
}
}
} else {
return this.textures[0];
}
}
getTextures( ) {
return this.textures;
}
addTexture(texture, face) {
this.textures.push({texture: texture, face : face});
}
/**
* bind sampler to shader
* @param {(shader)} shader
**/
bind( shader ) {
//this.cubeTexture
var glTexture = this.cubeTexture;
this.gl.enable ( this.gl.BLEND ) ;
this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, glTexture );
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, this.FLIP_Y);
if(!this.binded)
this.id = shader.samplerId++;
//this.gl.activeTexture(this.gl.TEXTURE_2D + this.id);
for(var c = 0; c<this.textures.length; c++) {
var texture = this.textures[c].texture;
if (texture.dataType == "framebuffer" ) {
//texture.glTexture = texture.data;
var type = texture.type;
} else {
var type = texture.dataType;
}
var data = texture.data;
var face = this.textures[c].face;
//this.gl.activeTexture(this.gl.TEXTURE_2D + this.id + c);
this.type = type;
console.log("binding", texture, data );
var mips = [];
var width = texture.width;
var height = texture.height;
//serialize texture data type
switch( type ) {
case "float":
this.gl.texImage2D(face, 0, this.format, width, height, 0, this.internalFormat, this.gl.FLOAT, data);
break;
case "int":
this.gl.texImage2D(face, 0, this.format, width, height, 0, this.internalFormat, this.gl.UNSIGNED_BYTE, data);
break;
case "depth":
this.gl.texImage2D(face, 0, this.gl.DEPTH_COMPONENT, width, height, 0, this.gl.DEPTH_COMPONENT, this.gl.UNSIGNED_SHORT, null);
break;
case "image":
this.gl.texImage2D(face, 0, this.format, this.internalFormat, this.gl.UNSIGNED_BYTE, data);
break;
case "canvas":
this.gl.texImage2D(face, 0, this.format, width, height, 0, this.internalFormat, this.UNSIGNED_BYTE, data);
break;
case "COMPRESSED_RGBA":
//var textureCompression = kepler.extensions.textureCompression;
var mipmaps = texture.mipmaps;
var width = mipmaps[0].width;
var height = mipmaps[0].height;
for(var i = 0; i < mipmaps.length; i++) {
var mipmap = mipmaps[i];
this.gl.compressedTexImage2D(texture.face, i, mipmap.internalFormat, mipmap.width, mipmap.height, 0, mipmap.byteArray);
}
break;
}
if (math.isPowerOfTwo(width) && math.isPowerOfTwo(height) ) {
// this.gl.texParameteri(this.target, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
// this.gl.texParameteri(this.target, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);// mipmaps > 1 ? this.gl.LINEAR_MIPMAP_LINEAR : this.gl.LINEAR
// this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.WRAP_S);
// this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.WRAP_T);
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
//this.gl.generateMipmap(this.gl.TEXTURE_2D);
} else {
this.gl.texParameteri(this.target, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
}
this.gl.bindTexture(this.target, null);
this.binded = true;
}
}
export {samplerCube as default};

103
engine/scene.js Executable file
View File

@@ -0,0 +1,103 @@
/*
* Copyright 2013-2019, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import entity from './entity.js';
/**
* Scene Node
**/
class scene{
rootEntity;
entitys = [];
/**
* add entity to scene
* @param {(entity)} entity
**/
addEntity(entity){
this.entitys.push(entity);
}
getLights(){
var lightEntitys = [];
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].type == "pointLight" || this.entitys[c].type == "skyLight")
lightEntitys.push( this.entitys[c] );
}
if(lightEntitys.length == 0) {
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 18.1, -10.01];
light.type = "skyLight";
//light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
//light.showFrustum = true;
light.degrees = 70;
lightEntitys.push( light );
this.entitys.push( light );
}
return lightEntitys;
}
/**
* get entity's
* @param {(entity)} entity
**/
getEntitys(entity){
return this.entitys;
}
getEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
return this.entitys[c];
}
}
getEntityByID(id){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].id == id)
return this.entitys[c];
}
}
getEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
return this.entitys[c];
}
}
removeEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
this.entitys.splice(c, 1);
}
var children = kepler.system.scene.rootEntity.children[0].children;
for(var c = 0; c<children.length;c++) {
if(children[c].name == name)
children.splice(c, 1);
}
}
}
export {scene as default};

76
engine/sceneNode.js Executable file
View File

@@ -0,0 +1,76 @@
/*
* Copyright 2013-2019, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* Scene Node
**/
class sceneNode{
rootEntity;
entitys = [];
/**
* add entity to sceneNode
* @param {(entity)} entity
**/
addEntity(entity){
this.entitys.push(entity);
}
/**
* get entity's
* @param {(entity)} entity
**/
getEntitys(entity){
return this.entitys;
}
getEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
return this.entitys[c];
}
}
getEntityByID(id){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].id == id)
return this.entitys[c];
}
}
getEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
return this.entitys[c];
}
}
removeEntityByName(name){
for(var c = 0; c<this.entitys.length;c++) {
if(this.entitys[c].name == name)
this.entitys.splice(c, 1);
}
var children = kepler.system.scene.rootEntity.children[0].children;
for(var c = 0; c<children.length;c++) {
if(children[c].name == name)
children.splice(c, 1);
}
}
}
export {sceneNode as default};

1012
engine/shader.js Executable file
View File

File diff suppressed because it is too large Load Diff

1399
engine/shader.js.new Normal file
View File

File diff suppressed because it is too large Load Diff

109
engine/skeleton.js Executable file
View File

@@ -0,0 +1,109 @@
kepler.skeleton(){
this.root;
this.bones = [];
this.name;
this.rootTransformation;
this.delta = 0;
this.currentAnimationMatrix;
}
kepler.skeleton.prototype.parse( boneInfo, rootNode ) {
var bone = kepler.createObject("bone");
this.rootTransformation = kepler.matrix4.fromArray( rootNode.transformation );
bone.isRoot = true;
bone.transformation = kepler.matrix4.fromArray( boneInfo.transformation );
bone.globalTransformation = bone.transformation;
this.bones.push(bone);
this.root = bone;
for(var c = 0; c < boneInfo.children.length; c++) {
this.parseChild(bone, boneInfo.children[c]);
}
}
kepler.skeleton.prototype.parseChild( parentBone, childBoneInfo ) {
var bone = kepler.createObject("bone");
bone.parent = parentBone;
bone.transformation = kepler.matrix4.fromArray( childBoneInfo.transformation );
bone.name = childBoneInfo.name;
bone.globalTransformation = kepler.matrix4.mul( bone.transformation, parentBone.globalTransformation );
this.bones.push(bone);
parentBone.addChild(bone);
//parse Children
if(childBoneInfo.children)
for(var c = 0; c < childBoneInfo.children.length; c++) {
this.parseChild(bone, childBoneInfo.children[c]);
}
}
kepler.skeleton.prototype.getBoneByName( name ) {
var bones = this.bones;
for(var c = 0; c < bones.length; c++) {
var bone = bones[c];
if(bone.name == name)
return bone;
}
}
kepler.skeleton.prototype.parseAnimation( channels ) {
for(var c = 0; c < channels.length; c++) {
var channel = channels[c];
var name = channel.name;
var bone = this.getBoneByName(name);
if(bone) {
bone.positionkeys = channel.positionkeys;
bone.rotationkeys = channel.rotationkeys;
}
}
}
kepler.skeleton.prototype.animate( bone, id ) {
bone.currentAnimationMatrix = kepler.matrix4.identity();
if(bone.positionkeys) {
if(bone.positionkeys[id]) {
var currentTranslation = bone.positionkeys[id][1];
bone.currentAnimationMatrix = kepler.matrix4.setTranslation(bone.currentAnimationMatrix, currentTranslation);
}
if(bone.rotationkeys[id]) {
var currentRotation = bone.rotationkeys[id][1];
bone.currentAnimationMatrix = kepler.matrix4.rotateZYX(bone.currentAnimationMatrix, currentRotation);
}
//console.log(bone.currentAnimationMatrix);
if(bone.parent)
bone.globalTransformation = kepler.matrix4.mul( bone.currentAnimationMatrix, bone.parent.globalTransformation );
//else
// bone.globalTransformation = kepler.matrix4.identity();
}
return bone;
}

42
engine/sky.js Executable file
View File

@@ -0,0 +1,42 @@
kepler.sky(){
this.shader;
this.sphereMesh;
this.entity;
this.create();
}
kepler.sky.prototype.create() {
var texture = kepler.resources.getTexture("sky");
var skySampler = new sampler2D();
skySampler.texture = texture;
this.shader = new shader();
this.shader.createFomFile("shaders/sky.shader");
this.shader.setUniform('textureSampler', skySampler);
this.shader.setUniform('g_AtmosphereBrightColor', [1.0,1.1,1.4]);
this.shader.setUniform('g_AtmosphereDarkColor', [0.6,0.6,0.7]);
var sphereMesh = kepler.primitives.createSphere(570, 16, 16);
var mesh = new mesh();
mesh.name = 'skySphere';
mesh.addSubMesh(sphereMesh);
this.entity = new entity();
this.entity.addMesh(mesh);
this.entity.transform.translate(0, 500, 0);
this.entity.shader = this.shader;
}
kepler.sky.prototype.update(){
this.entity.shader.setUniform('g_LightPosition', kepler.sunLight.position);
this.entity.shader.setUniform('g_CameraPosition', kepler.mainCamera.eye);
}

39
engine/subEntity.js Executable file
View File

@@ -0,0 +1,39 @@
/*
* Copyright 2019, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* sub Entity
**/
class subEntity {
subMeshes = [];
/**
* add subMesh
* @param {(submesh)} submesh
**/
addSubMesh(submesh) {
this.subMeshes.push(submesh);
}
/**
* get all submeshes
**/
getSubMeshes() {
return this.subMeshes;
}
/**
* parse subEntity (Deprecated)
* @param {(submesh)} submesh
**/
parse(submesh) {
}
};

23
engine/subMesh.js Executable file
View File

@@ -0,0 +1,23 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* subMesh object
**/
class subMesh{
_className = 'subMesh';
indices;
vertices;
textcoords;
normals;
material;
};
export {subMesh as default};

42
engine/texture.js Executable file
View File

@@ -0,0 +1,42 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
/**
* texture
**/
class texture{
constructor( ){
this.data;
this.dataType = false;
this.width = 1024;
this.height = 1024;
this.name;
this.address;
this.glTexture = gl.createTexture();
this.face = gl.TEXTURE_2D;//this.gl2.TEXTURE_CUBE_MAP_POSITIVE_X
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
this.glTexture = this.gl.createTexture();
this.face = this.gl.TEXTURE_2D;//this.gl2.TEXTURE_CUBE_MAP_POSITIVE_X
}
}
export {texture as default};

91
engine/transform.js Executable file
View File

@@ -0,0 +1,91 @@
/*
* Copyright 2013, kaj dijkstra ,
* Author, Kaj Dijkstra.
* All rights reserved.
*
*/
import {matrix4, math} from './math.js';
class transform{
constructor() {
this.entity = false;
this.world = matrix4.identity();
this.local = matrix4.identity();
this.position = [0, 0, 0];
this.scale = [1, 1, 1];
this.rotation = [0, 0, 0];//Degrees
}
translate(x,y,z) {
this.position[0] += x;
this.position[1] += y;
this.position[2] += z;
}
translateTo(x,y,z) {
this.position = [x,y,z];
this.update();
}
update(x,y,z) {
this.local = matrix4.identity();
this.local = matrix4.translate(this.local, this.position);
this.local = matrix4.rotateZYX(this.local, [this.rotation[0] * ( Math.PI * 180), this.rotation[1]* ( Math.PI * 180), this.rotation[2]* ( Math.PI * 180)]);
this.local = matrix4.scale(this.local, this.scale);
//if(this.entity) {
//this.world = matrix4.mul( this.local, this.entity.parent.transform.world );
this.world = this.local;
//}
}
scaleXYZ(x,y,z) {
this.scale = [x,y,z];
this.update();
}
rotate(x,y,z) {
}
rotateTo(x,y,z) {
this.rotation = [x,y,z];
this.update();
}
rotateZ(x) {
this.world = matrix4.rotateZ( this.world, math.degToRad( x ) );
}
rotateX(x) {
this.world = matrix4.rotateX( this.world, math.degToRad( x ) );
}
rotateY(y) {
this.world = matrix4.rotateY( this.world, math.degToRad( y ) );
}
getWorldPosition(y) {
return [this.world[3][0], this.world[3][1], this.world[3][2]];
}
getUpdatedWorldMatrix() {
return this.world;
}
translateVec(v) {
this.world = matrix4.translate(this.world, v);
}
}
export {transform as default};

120
engine/utils.js Executable file
View File

@@ -0,0 +1,120 @@
var WebGLUtils = function() {
/**
* Creates the HTLM for a failure message
* @param {string} canvasContainerId id of container of th
* canvas.
* @return {string} The html.
*/
var makeFailHTML = function(msg) {
return '' +
'<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
'<td align="center">' +
'<div style="display: table-cell; vertical-align: middle;">' +
'<div style="">' + msg + '</div>' +
'</div>' +
'</td></tr></table>';
};
/**
* Mesasge for getting a webgl browser
* @type {string}
*/
var GET_A_WEBGL_BROWSER = '' +
'This page requires a browser that supports Webthis.gl.<br/>' +
'<a href="http://get.webthis.gl.org">Click here to upgrade your browser.</a>';
/**
* Mesasge for need better hardware
* @type {string}
*/
var OTHER_PROBLEM = '' +
"It doesn't appear your computer can support Webthis.gl.<br/>" +
'<a href="http://get.webthis.gl.org/troubleshooting/">Click here for more information.</a>';
/**
* Creates a webgl context. If creation fails it will
* change the contents of the container of the <canvas>
* tag to an error message with the correct links for Webthis.gl.
* @param {Element} canvas. The canvas element to create a
* context from.
* @param {WebGLContextCreationAttirbutes} opt_attribs Any
* creation attributes you want to pass in.
* @param {function:(msg)} opt_onError An function to call
* if there is an error during creation.
* @return {WebGLRenderingContext} The created context.
*/
var setupWebGL = function(canvas, opt_attribs, opt_onError) {
function handleCreationError(msg) {
var container = canvas.parentNode;
if (container) {
var str = window.WebGLRenderingContext ?
OTHER_PROBLEM :
GET_A_WEBGL_BROWSER;
if (msg) {
str += "<br/><br/>Status: " + msg;
}
container.innerHTML = makeFailHTML(str);
}
};
opt_onError = opt_onError || handleCreationError;
if (canvas.addEventListener) {
canvas.addEventListener("webglcontextcreationerror", function(event) {
opt_onError(event.statusMessage);
}, false);
}
var context = create3DContext(canvas, opt_attribs);
if (!context) {
if (!window.WebGLRenderingContext) {
opt_onError("");
}
}
return context;
};
/**
* Creates a webgl context.
* @param {!Canvas} canvas The canvas tag to get context
* from. If one is not passed in one will be created.
* @return {!WebGLContext} The created context.
*/
var create3DContext = function(canvas, opt_attribs) {
var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
var context = null;
for (var ii = 0; ii < names.length; ++ii) {
try {
context = canvas.getContext(names[ii], opt_attribs);
} catch(e) {}
if (context) {
break;
}
}
return context;
}
return {
create3DContext: create3DContext,
setupWebGL: setupWebGL
};
}();
/**
* Provides requestAnimationFrame in a cross browser way.
*/
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000/60);
};
})();
export {WebGLUtils as default};

94
engine/viewport.js Executable file
View File

@@ -0,0 +1,94 @@
import renderSystem from './renderSystem.js';
import player from './player.js';
import eventManager from './eventManager.js';
import camera from './camera.js';
import scene from './scene.js';
import quad from './quad.js';
import primitives from './primitives.js';
import sampler2D from './sampler2D.js';
import linePrimitives from './linePrimitives.js';
/**
* viewport
**/
class viewport{
constructor( selector ){
this.width; // width of canvas
this.height; // height of canvas
this.selector = selector; // Dom selector
this.gl; // gl context
if(selector)
this.setup();
}
setSelector(selector) {
this.selector = selector;
}
setup() {
this.system = new renderSystem();
this.scene = new scene();
this.system.setViewport( this );
this.system.setGraphicsLibrary("WebGL_1.0");
this.canvas = document.getElementById( this.selector );
this.gl = this.system.initializeWebgl( this.canvas );
this.width = this.canvas.width;
this.height = this.canvas.height;
// Viewport dependend objects
this.mainPlayer = new player();
this.events = new eventManager( this );
this.mainCamera = new camera();
this.scene = new scene();
this.quad = new quad();
this.primitives = new primitives();
this.linePrimitives = new linePrimitives();
this.linePrimitives.setViewport( this );
this.primitives.setViewport( this );
this.quad.setViewport( this );
this.mainPlayer.setViewport( this );
this.mainCamera.setViewport( this );
//this.system.createRenderPasses2();
//createRenderPasses2
//this.events.setViewport( this );
}
addScene( scene ){
this.scene = scene;
}
render(){
this.mainPlayer.update();
this.mainCamera.update();
}
}
export {viewport as default};

236
index.html Executable file
View File

@@ -0,0 +1,236 @@
<html>
<head>
<title>Kepler</title>
<script src="media/libs/jquery/jquery.js"></script>
</head>
<script>
var kepler;
var gl;
var gl2;
</script>
<script type="module">
import keplerEngine from './engine/kepler.js';
import entity from './engine/entity.js';
import material from './engine/material.js';
import sampler2D from './engine/sampler2D.js';
import samplerCube from './engine/samplerCube.js';
import mesh from './engine/mesh.js';
import viewport from './engine/viewport.js';
import {matrix4} from './engine/math.js';
import template from './engine/renderPasses/template.js';
import scene from './engine/scene.js';
kepler = new keplerEngine();
var ViewPort = new viewport("keplerEngine");
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
var light = new entity( );
light.name = "skylight";
light.transform.position = [0, 18.1, -10.01];
light.type = "skyLight";
//light.type = "pointLight";
light.transform.direction = [0, -4, -0.01];
//.showFrustum = true;
light.degrees = 70;
ViewPort.scene.addEntity( light );
//ViewPort.system.setRenderMode("deferred");
ViewPort.system.reflectionSampler = new samplerCube();
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_x.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_x.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_y.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_y.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/positive_z.png"), gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
ViewPort.system.reflectionSampler.addTexture(kepler.resources.getTexture("cubemaps-1024/negative_z.png"), gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
var materialNames = ["plasticpattern1", "scuffed-plastic", "rustediron-streaks", "octostone", "paint-peeling", "wornpaintedcement", "pockedconcrete1", "hardwood-brown-planks", "darktiles1"];
for(var c = 0; c < materialNames.length; c++) {
var materialName = materialNames[c];
var x = (400 * c) % 1200;
var y = Math.floor(c / 3) * 400;
if(c != 4)
createMeshInstance( materialName, [x-400, 0, y-400],5, ViewPort);
}
function createMeshInstance(textureName, position, index, currentViewport ) {
console.log(textureName);
var diffuseTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-albedo.png" );
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
var normalTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-normal.png" );
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var roughnessTexture = kepler.resources.getTexture( "pbr-512/"+textureName+"/"+textureName+"-roughness"+".png" );
var roughnessSampler = new sampler2D();
roughnessSampler.addTexture(roughnessTexture);
var instanceMaterial = new material();
instanceMaterial.addTexture(diffuseSampler);
instanceMaterial.addNormal(normalSampler);
//instanceMaterial.addRoughness(roughnessSampler);
//instanceMaterial.shadingModelID = material.id;
instanceMaterial.alpha = 1;
instanceMaterial.create();
instanceMaterial.roughness = .2;
console.log(currentViewport.scene);
//copyMesh
var oldEntity = ViewPort.scene.getEntityByName("GrayInlay");
var oldMesh = oldEntity.mesh;
var meshCopy = new mesh();
// old way
//meshCopy.createMeshFromArrays( oldMesh.indices,
// oldMesh.vertices,
// oldMesh.normals,
// oldMesh.textureCoordinates,
// oldMesh.tangents,
// oldMesh.binormals );
meshCopy.copyMesh( oldMesh );
meshCopy.addMaterial(instanceMaterial);
var cloneEntity = new entity();
cloneEntity.parent = ViewPort.scene.entitys[index].parent;
cloneEntity.addMesh( meshCopy );
cloneEntity.name = textureName;
cloneEntity.transform.position = position;
cloneEntity.transform.update();
currentViewport.scene.addEntity( cloneEntity );
}
kepler.addViewport( ViewPort );
// Material
var groundMaterial = new material();
// Samplers
var normalTexture = kepler.resources.getTexture("0_floorTiles_ddn.png");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("0_floorTiles_diff.png");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
//groundMaterial.addRoughness(normalSampler);
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.1;
groundMaterial.roughness = 0.2;
groundMaterial.metalic = 0.4;
groundMaterial.uvMultiplier = 6;
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
//cubeMesh.draw_type = gl.POINTS;
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
var cubeMesh = ViewPort.primitives.createCube(1);
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "wireframe cube2";
cubeEntity.transform.position = [0, 1, 0];
cubeEntity.transform.update();
//ViewPort.scene.addEntity( cubeEntity );
var skyMaterial = new material();
skyMaterial.roughness = 0.4;
skyMaterial.diffuseColor = [179/256,199/256,217/256];
skyMaterial.alpha = 1;
skyMaterial.uvMultiplier = 6;
skyMaterial.shadingModelID = 100.0;
ViewPort.scene.getEntityByName("GrayInlay").mesh.material.diffuseColor = [1,1,1];
var sphere = ViewPort.primitives.createSphere(150, 200, 200)
sphere.addMaterial(skyMaterial);
var box = new entity( );
box.addMesh(sphere);
box.name = "sky sphere";
box.transform.position = [0, 0, 0];
box.transform.update();
ViewPort.scene.addEntity( box );
kepler.application();
</script>
<body style="margin: 0; padding: 0;">
<canvas id="keplerEngine" style="width: 100%; height: 100%; float:left;"></canvas>
</body>
</html>

BIN
media/3.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

BIN
media/4.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

BIN
media/aa.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
media/asd.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

BIN
media/diffuse.png Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

126
media/examples.js Executable file
View File

@@ -0,0 +1,126 @@
import keplerEngine from './engine/kepler.js';
import entity from './engine/entity.js';
import material from './engine/material.js';
import sampler2D from './engine/sampler2D.js';
import mesh from './engine/mesh.js';
import viewport from './engine/viewport.js';
import {matrix4} from './engine/math.js';
import template from './engine/renderPasses/template.js';
import sceneNode from './engine/sceneNode.js';
kepler = new keplerEngine();
// Viewport
var ViewPort = new viewport("keplerEngine");
// Load model
kepler.assimpLoader.load( "demo.json", ViewPort.scene );
// Add viewport
kepler.addViewport( ViewPort );
// Material
var groundMaterial = new material();
// Samplers
var normalTexture = kepler.resources.getTexture("floorTiles_normal");
var normalSampler = new sampler2D();
normalSampler.addTexture(normalTexture);
var diffuseTexture = kepler.resources.getTexture("floorTiles_diff");
var diffuseSampler = new sampler2D();
diffuseSampler.addTexture(diffuseTexture);
groundMaterial.addTexture(diffuseSampler);
groundMaterial.addNormal(normalSampler);
//groundMaterial.addRoughness(normalSampler);
// Properties
groundMaterial.diffuseColor = [179/256,199/256,217/256];
groundMaterial.alpha = 1;
groundMaterial.reflection = 0.2;
groundMaterial.roughness = 0.3;
groundMaterial.metalic = 0.1;
groundMaterial.uvMultiplier = 6;
groundMaterial.create();
// Cube mesh
var cubeMesh = ViewPort.primitives.createCube(10);
cubeMesh.addMaterial(groundMaterial);
// Cube Entity
var cubeEntity = new entity( );
cubeEntity.addMesh( cubeMesh );
cubeEntity.name = "sky sphere";
cubeEntity.transform.position = [0, -10, 0];
cubeEntity.transform.update();
ViewPort.scene.addEntity( cubeEntity );
// Start application
kepler.application();
// Template.js
import framebuffer from '../framebuffer.js';
import sampler2D from '../sampler2D.js';
import {math, vector3, matrix4} from '../math.js';
import samplerCube from '../samplerCube.js';
import shader from '../shader.js';
class template {
/**
* set viewport
* @param {(viewport)} viewport
**/
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
}
prepare() {
this.width = this.viewport.width;
this.height = this.viewport.height;
this.targetSampler = new sampler2D( );
this.targetSampler.type = this.gl.FLOAT;
this.framebuffer = new framebuffer( );
this.framebuffer.setViewport( this.viewport );
this.framebuffer.width = this.width;
this.framebuffer.height = this.height;
this.framebuffer.addSampler( this.targetSampler );
this.framebuffer.create();
this.shader = new shader();
this.shader.createFromFile("shaders/template.shader");
this.shader.setUniform("viewProjection", this.viewport.quad.viewProjection );
}
render() {
//this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer.glFramebuffer);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
this.gl.clearColor( 0, 0, 0, 1 );
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
this.viewport.quad.draw( this.shader );
}
}
export {template as default};

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More