<head>
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500&display=swap" rel="stylesheet">
<title>BABYLON js Template by Hitesh Sahu</title>
</head>
<body>
<div class="container">
<div class="container"><canvas id="renderCanvas" class="container" /></div>
<div class="footer"><a href = "https://hiteshsahu.com/lab">See More in Lab 🧪</a></div>
<div class="header"><h2>BABYLON JS Template by Hitesh Sahu<h2></div>
</div>
</body>
<link href="https://fonts.googleapis.com/css2?family=Lobster&display=swap" rel="stylesheet">
#renderCanvas {
position: absolute;
width: 100%;
height: 100%;
touch-action: none;
left: 0%;
right: 0%;
bottom:0%;
top: 0%;
}
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Rajdhani', sans-serif;
color: white;
font-size: large;
}
a:link, a:visited {
background-color: #f44336;
color: white;
padding: 14px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
}
.container {
position: relative;
height: 100%;
width: 100%;
}
.header {
position: absolute;
left:0;
right:0;
top:0;
padding-left:10px;
text-align: center;
}
.footer {
position: absolute;
right:0;
bottom:0;
margin:5px;
padding:5px;
}
a:hover, a:active {
background-color: red;
}
.center {
position: absolute;
background-color: #00bfa5;
left: 0%;
right: 0%;
bottom:0%;
top: 0%;
margin:10px;
padding:10px;
}
const GROUND_SIZE = 30
const VELOCITY = 70
const MIN_HEIGHT = 3;
const MAX_HEIGHT = 1
const TEXTURE_FOLDER = "https://www.babylonjs-playground.com/textures/"
const TEXTURES= {
Wood: "https://images.pexels.com/photos/172288/pexels-photo-172288.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
Dirt: TEXTURE_FOLDER+ "ground.jpg",
Ground: TEXTURE_FOLDER+ "ground.jpg",
Fur: "https://images.pexels.com/photos/801243/pexels-photo-801243.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
}
let projectiles= []
const options = {
highlightPickedItem: false,
useSkyBox: true,
showFog: true
}
var lastClickedMesh = null
//------------------- init Scene---------------------
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
var scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color3.FromHexString("#263238")
//Add Physics
var ammo = new BABYLON.CannonJSPlugin(true);
scene.enablePhysics(new BABYLON.Vector3(0, -10, 0), ammo);
// --------------------Add Camera--------------------
var camera = new BABYLON.ArcRotateCamera("Camera",
Math.PI / 2, Math.PI / 2, 40, BABYLON.Vector3.Zero(), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
camera.lowerBetaLimit = 0.1;
camera.upperBetaLimit = (Math.PI / 2) * 0.9;
camera.lowerRadiusLimit = 3;
camera.upperRadiusLimit = GROUND_SIZE * 2;
camera.setPosition(new BABYLON.Vector3(GROUND_SIZE / 2, 5, GROUND_SIZE / 2))
//-------------------- Lights -------------------------------
//Light for Gtlf
var ambientLight = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
ambientLight.intensity = 0.25;
//SunLight
// var sunLight = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -10, -1), scene);
// sunLight.position = new BABYLON.Vector3(GROUND_SIZE , GROUND_SIZE / 4, GROUND_SIZE );
// sunLight.intensity = 5;
var sunLight = new BABYLON.SpotLight("sunLight",
new BABYLON.Vector3(GROUND_SIZE/2 , GROUND_SIZE / 2, GROUND_SIZE/2),
new BABYLON.Vector3(-1, -1, -1),
Math.PI/2 , 1, scene);
sunLight.diffuse = BABYLON.Color3.FromHexString("#e25822")
sunLight.diffuse = new BABYLON.Color3.FromHexString("#F96229"); //(1, 1, 1);
sunLight.specular = new BABYLON.Color3.FromHexString("#FCE13D");
sunLight.intensity = 5;
//Imposter for sun
var lightImposter = BABYLON.Mesh.CreateSphere("lightImposter", 10, 2, scene);
var lightImposterMat = new BABYLON.StandardMaterial("lightImposterMat", scene);
lightImposterMat.diffuseColor = new BABYLON.Color3(1, 1, 0);
lightImposterMat.emissiveColor = new BABYLON.Color3(1, 1, 0);
lightImposter.material = lightImposterMat
lightImposter.position = sunLight.position;
// Shadows
var shadowGenerator = new BABYLON.ShadowGenerator(1024, sunLight);
shadowGenerator.darkness = .25
shadowGenerator.useExponentialShadowMap = true;
//Make meshes glow
new BABYLON.GlowLayer("glow", scene, {
mainTextureFixedSize: 1024,
blurKernelSize: 64
});
//---------------Skybox----------------------
if (options.useSkyBox) {
var skyboxMesh = BABYLON.Mesh.CreateBox("skyBox", GROUND_SIZE * 4, scene);
var skyboxMaterial = new BABYLON.StandardMaterial("skyboxMaterial", scene);
skyboxMaterial.backFaceCulling = false;
skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture(TEXTURE_FOLDER+ "skybox", scene);
skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
skyboxMaterial.reflectionTexture.boundingBoxSize = null;
skyboxMesh.material = skyboxMaterial;
}
//Fog!
if(options.showFog){
scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR;
scene.fogColor = scene.clearColor;
scene.fogDensity = 0.01;
scene.fogStart = 20.0;
scene.fogEnd = 100.0;
}
//------------------Add Ground---------------
var groundMesh = BABYLON.MeshBuilder.CreateGroundFromHeightMap("groundMesh",
TEXTURE_FOLDER+"heightMap.png",
{
width: GROUND_SIZE,
height: GROUND_SIZE,
subdivisions: 100,
minHeight: MIN_HEIGHT,
maxHeight: MAX_HEIGHT,
onReady: () => {
var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
groundMaterial.diffuseTexture = new BABYLON.Texture(TEXTURES.Dirt, scene);
groundMaterial.diffuseTexture.uScale = 3;
groundMaterial.specularColor = BABYLON.Color3.Black()
groundMesh.material = groundMaterial;
// //Shadow
groundMesh.receiveShadows = true;
groundMesh.isPickable = true
//Physics
groundMesh.physicsImpostor =
new BABYLON.PhysicsImpostor(groundMesh,
BABYLON.PhysicsImpostor.HeightmapImpostor,
{
mass: 0,
restitution: 0.5,
friction: 1
}, scene);
}
}, scene);
//------------------Meshes---------------------------
var sphereMesh = BABYLON.MeshBuilder.CreateSphere("sphereMesh",
{ diameter: 2, segments: 32 }, scene);
sphereMesh.position.y = 5;
shadowGenerator.addShadowCaster(sphereMesh);
var mat = new BABYLON.StandardMaterial("toto", scene);
mat.specularTexture = new BABYLON.Texture(TEXTURE_FOLDER+"specularglossymap.png", scene);
mat.specularPower = 64;
mat.useGlossinessFromSpecularMapAlpha = true;
mat.diffuseColor = BABYLON.Color3.Black();
mat.roughness = 3;
mat.reflectionTexture = new BABYLON.CubeTexture(TEXTURE_FOLDER +"skybox", scene);
sphereMesh.material = mat;
sphereMesh.physicsImpostor = new BABYLON.PhysicsImpostor(sphereMesh, BABYLON.PhysicsImpostor.SphereImpostor,{
mass: 0.5,
restitution: 1,
friction: .25
}, scene);
// Add and manipulate meshes in the scene
var boxMesh = BABYLON.MeshBuilder.CreateBox("boxMesh", {
height: 2,
width: 2,
depth: 2,
updatable: true
});
shadowGenerator.addShadowCaster(boxMesh);
boxMesh.position.y = 5
boxMesh.physicsImpostor = new BABYLON.PhysicsImpostor(boxMesh, BABYLON.PhysicsImpostor.BoxImpostor, {
mass: 0.5,
restitution: 1,
friction: .25
}, scene);
var boxMaterial = new BABYLON.StandardMaterial("boxMaterial", scene);
boxMaterial.diffuseTexture = new BABYLON.Texture(TEXTURES.Wood, scene);
boxMesh.material = boxMaterial;
for(let i= 0; i<20; i++) {
boxMesh.clone("boxMesh")
}
for(let i= 0; i<10; i++) {
boxMesh.clone("boxMesh")
sphereMesh.clone("boxMesh")
}
// create particles
var particle = BABYLON.MeshBuilder.CreateSphere(
"sphere",
{ diameter: 0.25, segments: 3 },
scene
);
var particleMaterial = new BABYLON.StandardMaterial("texture", scene);
particleMaterial.diffuseColor = new BABYLON.Color3(1, 0, 0);
particle.material = particleMaterial;
particle.isVisible = false;
let vertexes = boxMesh.getVerticesData(
BABYLON.VertexBuffer.PositionKind
);
for (let vertex = 0; vertex < vertexes.length; vertex += 3) {
let vertexMesh = particle.createInstance("s" + vertex)
vertexMesh.position = BABYLON.Vector3.FromArray(vertexes, vertex);
vertexMesh.parent = boxMesh
}
//-----------Event loop ----------------------------------
var angle = 0;
scene.registerBeforeRender(() => {
camera.alpha += 0.0025 * scene.getAnimationRatio();
angle += 0.01;
//Reset if out of bound
scene.meshes.forEach(mesh => {
if (mesh.position.y < -10) {
if (mesh.name === "boxMesh") {
mesh.position = new BABYLON.Vector3(
randomBetween(-GROUND_SIZE / 4, GROUND_SIZE / 4),
randomBetween(5, 15),
randomBetween(-GROUND_SIZE / 4, GROUND_SIZE / 4)
);
mesh.physicsImpostor.setLinearVelocity(BABYLON.Vector3.Zero());
mesh.physicsImpostor.setAngularVelocity(BABYLON.Vector3.Zero());
}
}
});
});
scene.onKeyboardObservable.add((kbInfo) => {
switch (kbInfo.type) {
case BABYLON.KeyboardEventTypes.KEYUP:
//console.log("KEY UP: ", kbInfo.event.keyCode);
switch (kbInfo.event.keyCode) {
case 87: //W
break;
case 65: //A
break;
case 83: //S
break;
case 68: //D
break;
case 32: //SPACE
break;
}
break;
}
});
var h1 = new BABYLON.HighlightLayer("hl", scene);
scene.onPointerObservable.add((pointerInfo) => {
switch (pointerInfo.type) {
case BABYLON.PointerEventTypes.POINTERDOWN:
let pickInfo = pointerInfo.pickInfo;
if (pickInfo.hit) {
// Shoot new Ball
let position = pickInfo.ray.origin;
let velocity = pickInfo.ray.direction.scale(VELOCITY);
shootBullet(position, velocity, scene)
//Do something with Picked Mesh
let pickedMesh = pickInfo.pickedMesh;
// HighLight Selected
if (pickedMesh) {
if (lastClickedMesh) {
h1.removeMesh(lastClickedMesh);
}
lastClickedMesh = pickedMesh;
if (options.highlightPickedItem)
h1.addMesh(lastClickedMesh, BABYLON.Color3.Green());
//Apply Bullet Force
pickedMesh.applyImpulse(
new BABYLON.Vector3(
Math.random() * 5,
Math.random() * 15,
Math.random() * 5
),
pickedMesh.position
);
}
}
break;
case BABYLON.PointerEventTypes.POINTERUP:
break;
case BABYLON.PointerEventTypes.POINTERMOVE:
break;
default:
break;
}
});
randomBetween = (max = 0, min = 0) => Math.floor(Math.random() * (max + 1 - min)) + min;
shootBullet = (position, velocity, scene) => {
if (projectiles.length > 10) {
projectiles.shift().dispose();
}
var ballMesh = BABYLON.Mesh.CreateSphere("boxMesh", 16, 2, scene);
ballMesh.position = position;
let ballmaterial = new BABYLON.StandardMaterial("cover", scene);
ballmaterial.diffuseTexture = new BABYLON.Texture(
TEXTURES.Fur
);
ballmaterial.emissiveTexture = new BABYLON.Texture(
TEXTURES.Fur
);
ballMesh.material = ballmaterial;
ballMesh.position.copyFrom(position);
ballMesh.physicsImpostor = new BABYLON.PhysicsImpostor(
ballMesh,
BABYLON.PhysicsImpostor.SphereImpostor,
{ mass: .5, restitution: 0.2 },
scene
);
ballMesh.physicsImpostor.setLinearVelocity(velocity);
ballMesh.physicsImpostor.setAngularVelocity(new BABYLON.Quaternion(2, 0, 2, 0));
projectiles.push(ballMesh);
};
engine.runRenderLoop(() => {
if (scene) scene.render();
});
// Resize
window.addEventListener("resize", () => {
engine.resize();
});
This Pen doesn't use any external CSS resources.