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

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};