How to add env map onto gltf object - javascript

Im having quite a bit of trouble adding an environment map to a loaded GLTF / GLB file, as of now I get some sort of reflection instead of a black dot with a light point on it,
I was reading a bit of the document for three js and think I can pull it off with the standardmeshmaterial and applying it somehow to the object(gltf) and adding the mesh into the scene. I tried a similar mockup but the item disappears. I dont know how to go about it, help guys.
This is the environment map im trying to apply to it, (or something similar)
https://hdrihaven.com/files/hdri_images/tonemapped/8192/venice_sunset.jpg
here is the codepen I am working on
https://codepen.io/8AD/pen/XWpxmpO
HTML
<script src="https://unpkg.com/three#0.87.1/build/three.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/d9f87fb1a2c5db1ea0e2feda9bd42b39b5bedc41/build/three.min.js"></script>
<!-- OrbitControls.js -->
<script src="https://rawcdn.githack.com/mrdoob/three.js/d9f87fb1a2c5db1ea0e2feda9bd42b39b5bedc41/examples/js/controls/OrbitControls.js"></script>
<!-- DRACOLoader.js -->
<script src="https://rawcdn.githack.com/mrdoob/three.js/d9f87fb1a2c5db1ea0e2feda9bd42b39b5bedc41/examples/js/loaders/DRACOLoader.js"></script>
<!-- GLTFLoader.js -->
<script src="https://rawcdn.githack.com/mrdoob/three.js/d9f87fb1a2c5db1ea0e2feda9bd42b39b5bedc41/examples/js/loaders/GLTFLoader.js"></script>
<div id="3dmain">
</div>
JS
var gltf = null;
var mixer = null;
var clock = new THREE.Clock();
var controls;
var camera;
init();
animate();
var renderCalls = [];
function render () {
requestAnimationFrame( render );
renderCalls.forEach((callback)=>{ callback(); });
}
render();
function init() {
width = window.innerWidth;
height = window.innerHeight;
scene = new THREE.Scene();
var light = new THREE.PointLight( 0xffffcc, 20, 200 );
light.position.set( 4, 30, 80 );
scene.add( light );
var light2 = new THREE.AmbientLight( 0x20202A, 20, 100 );
light2.position.set( 30, -10, 30 );
scene.add( light2 );
camera = new THREE.PerspectiveCamera( 60, width / height, 0.01, 10000 );
camera.position.set(0, 3, 10);
window.addEventListener( 'resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false );
var geometry = new THREE.BoxGeometry(100, 5, 100);
var material = new THREE.MeshLambertMaterial({
color: "#707070"
});
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
var loader = new THREE.GLTFLoader();
loader.setCrossOrigin( 'anonymous' );
var scale = 0.01;
var url = "https://8ad.studio/wp-content/uploads/3D%20Assets/blimp.glb";
loader.load(url, function (data) {
gltf = data;
var object = gltf.scene;
object.scale.set(scale, scale, scale);
//object.position.y = -5;
//object.position.x = 4;
object.castShadow = true;
object.receiveShadow = true;
var animations = gltf.animations;
if ( animations && animations.length ) {
mixer = new THREE.AnimationMixer( object );
for ( var i = 0; i < animations.length; i ++ ) {
var animation = animations[ i ];
mixer.clipAction( animation ).play();
}
}
scene.add(object);
});
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true } );
renderer.setClearColor( 0x000000, 0 );
renderer.shadowMap.enabled = true;
controls = new THREE.OrbitControls( camera,);
controls.rotateSpeed = 0.3;
controls.zoomSpeed = 0.9;
controls.minDistance = 14;
controls.maxDistance = 14;
controls.minPolarAngle = 0; // radians
controls.maxPolarAngle = Math.PI /2; // radians
controls.enableDamping = true;
controls.dampingFactor = 0.05;
var renderCalls = [];
renderCalls.push(function(){
controls.update()
});
renderer.setSize( width, height );
renderer.gammaOutput = true;
document.getElementById('3dmain').appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
if (mixer) mixer.update(clock.getDelta());
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
}

You have to include RGBELoader into your app for importing HDR textures and make use of PMREMGenerator in order to pre-process the environment map for the usage with a PBR material.
var gltf = null;
var mixer = null;
var clock = new THREE.Clock();
var controls;
var camera;
var renderer;
init();
animate();
var renderCalls = [];
function render() {
requestAnimationFrame(render);
renderCalls.forEach((callback) => {
callback();
});
}
render();
function init() {
width = window.innerWidth;
height = window.innerHeight;
scene = new THREE.Scene();
var light = new THREE.PointLight(0xffffcc, 20, 200);
light.position.set(4, 30, 80);
scene.add(light);
var light2 = new THREE.AmbientLight(0x20202A, 20, 100);
light2.position.set(30, -10, 30);
scene.add(light2);
camera = new THREE.PerspectiveCamera(60, width / height, 0.01, 10000);
camera.position.set(0, 3, 10);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.setClearColor(0x000000, 0);
renderer.shadowMap.enabled = true;
window.addEventListener('resize', function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
var geometry = new THREE.BoxGeometry(100, 5, 100);
var material = new THREE.MeshLambertMaterial({
color: "#707070"
});
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var scale = 0.01;
var url = "https://8ad.studio/wp-content/uploads/3D%20Assets/blimp.glb";
var loader = new THREE.GLTFLoader();
loader.setCrossOrigin('anonymous');
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
const rgbeLoader = new THREE.RGBELoader();
rgbeLoader.load('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', function(texture) {
const envMap = pmremGenerator.fromEquirectangular(texture).texture;
scene.background = envMap;
scene.environment = envMap;
texture.dispose();
pmremGenerator.dispose();
loader.load(url, function(data) {
gltf = data;
var object = gltf.scene;
object.scale.set(scale, scale, scale);
//object.position.y = -5;
//object.position.x = 4;
object.castShadow = true;
object.receiveShadow = true;
var animations = gltf.animations;
if (animations && animations.length) {
mixer = new THREE.AnimationMixer(object);
for (var i = 0; i < animations.length; i++) {
var animation = animations[i];
mixer.clipAction(animation).play();
}
}
scene.add(object);
});
});
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.rotateSpeed = 0.3;
controls.zoomSpeed = 0.9;
controls.minDistance = 14;
controls.maxDistance = 14;
controls.minPolarAngle = 0; // radians
controls.maxPolarAngle = Math.PI / 2; // radians
controls.enableDamping = true;
controls.dampingFactor = 0.05;
var renderCalls = [];
renderCalls.push(function() {
controls.update()
});
renderer.setSize(width, height);
document.getElementById('3dmain').appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
if (mixer) mixer.update(clock.getDelta());
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.127/build/three.js"></script>
<!-- OrbitControls.js -->
<script src="https://cdn.jsdelivr.net/npm/three#0.127/examples/js/controls/OrbitControls.js"></script>
<!-- DRACOLoader.js -->
<script src="https://cdn.jsdelivr.net/npm/three#0.127/examples/js/loaders/DRACOLoader.js"></script>
<!-- GLTFLoader.js -->
<script src="https://cdn.jsdelivr.net/npm/three#0.127/examples/js/loaders/GLTFLoader.js"></script>
<!-- RGBELoader.js -->
<script src="https://cdn.jsdelivr.net/npm/three#0.127/examples/js/loaders/RGBELoader.js"></script>
<div id="3dmain">
</div>
The example applies the environment map to Scene.environment. However, you could also traverse through the glTF object and apply it to each material's envMap property.

Related

How to make two canvas with two separate javascript code?

I am using Three.js to develop a cube that translates and rotate in 3D space using data from accelerometer and gyroscope data.
So far I have one canvas that shows the accelerometer movement. Now I need to have another canvas that shows the gyroscope data on a separate canvas, I prefer to have two JS code for each canvas, so they are independent of each other. I wasn't able to make two separate canvases, and I don't know if it is even possible to use two different javascript codes in the html.
Below is how my HTML is structured:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<canvas id="canvas" width="500" height="800" style="border:1px solid #eb1c1c;"></canvas>
<div id="info">
<div>t = <span id="time">0</span> s</div>
<div>accX = <span id="accX">0</span></div>
<div>accY = <span id="accY">0</span></div>
<div>accZ = <span id="accZ">0</span></div>
</div>
</body>
</html>
and this is the javascript:
import * as THREE from "three";
import data from "../data/data.json"
import "./style.css"
var width = window.innerWidth;
var height = window.innerHeight;
const canvas = document.querySelector('#canvas');
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.setSize (width, height);
var planeSize = 100000
const fov = 70;
const aspect = 2; // the canvas default
const near = 20;
const far = 500;
const camera = new THREE.PerspectiveCamera(70, width/height, 1, 10000);
camera.position.y = 3;
camera.position.z = 30;
camera.lookAt (new THREE.Vector3(0,0,0));
// camera.position.set(0, 40, 1.5);
// camera.up.set(0, 10, 1);
// camera.lookAt(0, 10, 0);
const scene = new THREE.Scene();
{
const color = 0x00afaf;
const intensity = 10;
const size = 10;
const divisions = 10;
const gridHelper = new THREE.GridHelper( planeSize, 5000 );
gridHelper.setColors( new THREE.Color(0xff0000), new THREE.Color(0xffffff) );
scene.add(gridHelper);
const light = new THREE.PointLight(color, intensity);
scene.add(light);
// scene.add( gridHelper );
}
// // label the axis
// var textGeo = new THREE.TextGeometry('Y', {
// size: 5,
// height: 2,
// curveSegments: 6,
// font: "helvetiker",
// style: "normal"
// });
// var color = new THREE.Color();
// color.setRGB(255, 250, 250);
// var textMaterial = new THREE.MeshBasicMaterial({ color: color });
// var text = new THREE.Mesh(textGeo , textMaterial);
// text.position.x = axis.geometry.vertices[1].x;
// text.position.y = axis.geometry.vertices[1].y;
// text.position.z = axis.geometry.vertices[1].z;
// text.rotation = camera.rotation;
// scene.add(text);
const boxGeometry = new THREE.BoxGeometry();
const boxMaterial = new THREE.MeshBasicMaterial({ color: "green", wireframe: false });
const object = new THREE.Mesh(boxGeometry, boxMaterial);
var cubeAxis = new THREE.AxesHelper(3);
object.add(cubeAxis);
object.scale.set(5, 5, 5)
scene.add(object);
scene.background = new THREE.Color(0.22, 0.23, 0.22);
let currentIndex = 0
let time = data[currentIndex].time
let velocity = new THREE.Vector3()
requestAnimationFrame(render);
function render(dt) {
dt *= 0.0001 // in seconds
time += dt
document.querySelector("#time").textContent = time.toFixed(2)
// Find datapoint matching current time
while (data[currentIndex].time < time) {
currentIndex++
if (currentIndex >= data.length) return
}
const { rotX, rotY, rotZ, accX, accY, accZ } = data[currentIndex]
document.querySelector("#accX").textContent = accX* 10;
document.querySelector("#accY").textContent = accY* 10;
document.querySelector("#accZ").textContent = accZ* 10;
const acceleration = new THREE.Vector3()
// object.rotation.set( rotX, rotY, rotZ)
object.position.x = accX * 30;
// object.position.add(velocity.clone().multiplyScalar(dt)).add(acceleration.clone().multiplyScalar(50 * dt ** 2))
// object.position.add(accZ)
// velocity.add(acceleration.clone().multiplyScalar(dt))
var relativeCameraOffset = new THREE.Vector3 (0,10,10);
var cameraOffset = relativeCameraOffset.applyMatrix4( object.matrixWorld );
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt( object.position );
resizeToClient();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function resizeToClient() {
const needResize = resizeRendererToDisplaySize()
if (needResize) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
}
function resizeRendererToDisplaySize() {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
this is how I want the canvas to look like:
Good news is it is possible, you just have to put all your code(at least animations) in separate functions :
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const scene1 = new THREE.Scene();
const camera1 = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
scene.background = new THREE.Color( 0xf0000f);
scene1.background = new THREE.Color( 0x0000ff );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
const renderer1 = new THREE.WebGLRenderer();
renderer1.setSize( window.innerWidth, window.innerHeight );
renderer1.domElement.width=500;
renderer1.domElement.height=300;
renderer1.domElement.style.position="absolute";
renderer1.domElement.style.top=0;
renderer1.domElement.style.height=150+"px";
renderer1.domElement.style.width=200+"px";
renderer.domElement.width=500;
renderer.domElement.height=300;
renderer.domElement.style.position="absolute";
renderer.domElement.style.top=0;
document.body.appendChild( renderer.domElement );
document.body.appendChild( renderer1.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
const geometry1 = new THREE.BoxGeometry(3,3,3);
const material1 = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube1 = new THREE.Mesh( geometry1, material1 );
scene1.add( cube1 );
camera.position.z = 5;
camera1.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
const animate1 = function () {
requestAnimationFrame( animate1 );
cube1.rotation.x += 0.01;
cube1.rotation.y += 0.01;
renderer1.render( scene1, camera1 );
};
animate();
animate1();
<script src="http://threejs.org/build/three.min.js"></script>

How to create a mesh out of an imported model in Three.js

Im trying to create a game using three.js, but I'm running into some issues regarding the imported 3D models. I've created them in Blender and used the gltf-blender-IO plugin to make it easier to work with. However, I can't exactly move the model without it being a mesh. How do I create a mesh out of the model in order to fix this issue?
The full code is here.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
// controls = new THREE.OrbitControls(camera, renderer.domElement);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
renderer.physicallyCorrectLights = true;
camera.position.z = 3;
// ambient light
var ambientLight = new THREE.AmbientLight(0xF0F0F0, 4.5);
scene.add(ambientLight);
// directional light
var directionalLight = new THREE.DirectionalLight(0xffffff, 5.0);
directionalLight.position.set(5, 0, 5);
directionalLight.target.position.set(0, 0, 0);
directionalLight.castShadow = true;
directionalLight.shadowDarkness = 0.5;
directionalLight.shadowCameraNear = 0;
directionalLight.shadowCameraFar = 15;
directionalLight.shadowCameraLeft = -5;
directionalLight.shadowCameraRight = 5;
directionalLight.shadowCameraTop = 5;
directionalLight.shadowCameraBottom = -5;
scene.add(directionalLight);
// Load a glTF resource
var loader = new THREE.GLTFLoader;
loader.load(
'Fox.glb',
function ( gltf ) {
scene.add( gltf.scene );
gltf.animations; // Array<THREE.AnimationClip>
gltf.scene; // THREE.Scene
gltf.scenes; // Array<THREE.Scene>
gltf.cameras; // Array<THREE.Camera>
gltf.asset; // Object
},
// called while loading is progressing
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
// end main
function update() {
};
function render() {
renderer.render(scene, camera);
};
function loop() {
window.requestAnimationFrame(loop);
update();
render();
}
loop();

How to have two Three-JS Objects run and animate at the same time?

I've created two 3JS objects and scenes for learning purposes. Both housed in separate PHP files (not in the jsfiddle). However, I can't figure out why by adding a second object the first object stops animating and doesn't run anymore? How can I go about figuring out why my objects are canceling one another out and how to create two different or more multiple threejs items that animate at the same time?
//GRID OBJ is the first object, and the second is //BALL
When I remove the second script calling for 3js ball the grid will animate, when the ball is added the grid stops animating and only the ball animates.
http://jsfiddle.net/tdqh4jno/
//GRID OBJ
var container = document.getElementById('grid')
var vertexHeight = 90,
planeDefinition = 25,
planeSize = 900,
totalObjects = 1,
background = "#002135",
meshColor = "#ff3057";
var camera2 = new THREE.PerspectiveCamera( 110, 1, 5)
camera2.position.y = 500;
var scene2 = new THREE.Scene();
scene2.background = new THREE.Color( 0x08080c);
var renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setClearColor( 0x000000, 0 );
var planeGeo = new THREE.PlaneGeometry(planeSize, planeSize, planeDefinition, planeDefinition);
var plane = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
color: meshColor,
wireframe: true
}));
plane.rotation.x -= Math.PI * .5;
scene2.add(plane);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(background, 1);
container.appendChild(renderer.domElement);
function updatePlane() {
for (var i = 0; i < planeGeo.vertices.length; i++) {
planeGeo.vertices[i].z += Math.random() * vertexHeight;
planeGeo.vertices[i]._myZ = planeGeo.vertices[i].z
}
};
var count = 0
function renderGrid() {
var gridSpeed = 0.4;
var gridInterlop = -0.4;
var gridWaveSpeed = 0.003;
var gridWaveHeight = 0.00003;
requestAnimationFrame(renderGrid);
for (var i = 0; i < planeGeo.vertices.length; i++) {
var z = +planeGeo.vertices[i].z;
planeGeo.vertices[i].z = Math.sin(( i + count * gridWaveHeight)) * (planeGeo.vertices[i]._myZ - (planeGeo.vertices[i]._myZ * gridWaveSpeed))
plane.geometry.verticesNeedUpdate = true;
count += gridInterlop
}
renderer.render(scene2, camera2);
}
updatePlane();
renderGrid();
//BALL ITEM
var camera2 = new THREE.PerspectiveCamera(100, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sceneTop = new THREE.Scene(); // initialising the scene
sceneTop.background = new THREE.Color( 0x08080c);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100,100,100);
spotLight.castShadow = false;
sceneTop.add(spotLight);
function Mat(){
var material = new THREE.MeshPhongMaterial({
color : new THREE.Color(0xff3266),
emissive : new THREE.Color(0x08080c),
specular : new THREE.Color(0x08080c),
shininess : 0,
wireframe : true,
transparent: 0.5,
opacity : 0.55
});
return material;
}
var geometry = new THREE.IcosahedronGeometry(45 , 1);
var obj = new THREE.Mesh(geometry, Mat());
sceneTop.add(obj);
camera2.position.z = 90;
function myrender(){
renderer.setClearColor( 0x000000, 0 );
obj.rotation.x += 0.0004;
obj.rotation.y += 0.0006;
obj.rotation.z += Math.random() * 0.0005;
renderer.render(sceneTop, camera2);
requestAnimationFrame(myrender);
}
window.addEventListener('resize', onWindowResize, true);
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera2.updateProjectionMatrix();
};
myrender();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<div id="grid"></div>
You create 2 THREE.WebGLRenderer objects, but both assigned to the variable renderer. This breaks down the animation of the first (grid) object in the function renderGrid.
In your code are created 2 different scenes referenced by 2 different variables (sceneTop, scene2). Create 2 different render objects, referenced by 2 different variables (renderer, renderer2), too:
var scene2 = new THREE.Scene();
scene2.background = new THREE.Color( 0x08080c);
var renderer2 = new THREE.WebGLRenderer({alpha: true});
renderer2.setClearColor( 0x000000, 0 );
// [...]
renderer2.setSize(window.innerWidth, window.innerHeight);
renderer2.setClearColor(background, 1);
container.appendChild(renderer2.domElement);
function renderGrid() {
// [...]
renderer2.render(scene2, camera2);
}
In the following you have to respect, that renderer corresponds to camera respectively sceneTop, but renderer2 corresponds to scene2 and camera2:
var camera = new THREE.PerspectiveCamera(100, window.innerWidth/window.innerHeight, 0.1, 1000);
[...]
camera.position.z = 90;
function myrender(){
// [...]
renderer.render(sceneTop, camera);
requestAnimationFrame(myrender);
}
See the example, where I applied the suggested changes to your original code:
//GRID OBJ
var container = document.getElementById('grid')
var vertexHeight = 90,
planeDefinition = 25,
planeSize = 900,
totalObjects = 1,
background = "#002135",
meshColor = "#ff3057";
var camera2 = new THREE.PerspectiveCamera( 110, 1, 5)
camera2.position.y = 500;
var scene2 = new THREE.Scene();
scene2.background = new THREE.Color( 0x08080c);
var renderer2 = new THREE.WebGLRenderer({alpha: true});
renderer2.setClearColor( 0x000000, 0 );
var planeGeo = new THREE.PlaneGeometry(planeSize, planeSize, planeDefinition, planeDefinition);
var plane = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
color: meshColor,
wireframe: true
}));
plane.rotation.x -= Math.PI * .5;
scene2.add(plane);
renderer2.setSize(window.innerWidth, window.innerHeight);
renderer2.setClearColor(background, 1);
container.appendChild(renderer2.domElement);
function updatePlane() {
for (var i = 0; i < planeGeo.vertices.length; i++) {
planeGeo.vertices[i].z += Math.random() * vertexHeight;
planeGeo.vertices[i]._myZ = planeGeo.vertices[i].z
}
};
var count = 0
function renderGrid() {
var gridSpeed = 0.4;
var gridInterlop = -0.4;
var gridWaveSpeed = 0.003;
var gridWaveHeight = 0.00003;
requestAnimationFrame(renderGrid);
for (var i = 0; i < planeGeo.vertices.length; i++) {
var z = +planeGeo.vertices[i].z;
planeGeo.vertices[i].z = Math.sin(( i + count * gridWaveHeight)) * (planeGeo.vertices[i]._myZ - (planeGeo.vertices[i]._myZ * gridWaveSpeed))
plane.geometry.verticesNeedUpdate = true;
count += gridInterlop
}
renderer2.render(scene2, camera2);
}
updatePlane();
renderGrid();
//BALL ITEM
var camera = new THREE.PerspectiveCamera(100, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sceneTop = new THREE.Scene(); // initialising the scene
sceneTop.background = new THREE.Color( 0x08080c);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100,100,100);
spotLight.castShadow = false;
sceneTop.add(spotLight);
function Mat(){
var material = new THREE.MeshPhongMaterial({
color : new THREE.Color(0xff3266),
emissive : new THREE.Color(0x08080c),
specular : new THREE.Color(0x08080c),
shininess : 0,
wireframe : true,
transparent: 0.5,
opacity : 0.55
});
return material;
}
var geometry = new THREE.IcosahedronGeometry(45 , 1);
var obj = new THREE.Mesh(geometry, Mat());
sceneTop.add(obj);
camera.position.z = 90;
function myrender(){
renderer.setClearColor( 0x000000, 0 );
obj.rotation.x += 0.0004;
obj.rotation.y += 0.0006;
obj.rotation.z += Math.random() * 0.0005;
renderer.render(sceneTop, camera);
requestAnimationFrame(myrender);
}
window.addEventListener('resize', onWindowResize, true);
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
renderer2.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
camera2.aspect = window.innerWidth / window.innerHeight;
camera2.updateProjectionMatrix();
};
myrender();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<div id="grid"></div>
Alternatively both scenes can be rendered to different parts of the viewport.
Create 1 THREE.WebGLRenderer, with the .autoClear property set to false:
var renderer = new THREE.WebGLRenderer({alpha: true, preserveDrawingBuffer: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000, 0 );
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
Render both scenes 2 different parts of the viewport. The viewport rectangle can be changed by .setViewport:
function myrender(){
// [...]
renderer.setViewport(0,0,window.innerWidth, window.innerHeight);
renderer.clear();
renderer.setViewport(window.innerWidth/2,0,window.innerWidth/2, window.innerHeight);
renderer.render(sceneTop, camera, 0, false);
renderer.setViewport(0,0,window.innerWidth/2, window.innerHeight);
renderer.render(scene2, camera2, 0, false);
requestAnimationFrame(myrender);
}
Ensure that the .background property is only set for the THREE.Scene which is rendered first.
See the example:
//GRID OBJ
var container = document.getElementById('grid')
var vertexHeight = 90,
planeDefinition = 25,
planeSize = 900,
totalObjects = 1,
background = "#002135",
meshColor = "#ff3057";
var renderer = new THREE.WebGLRenderer({alpha: true, preserveDrawingBuffer: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000, 0 );
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
var camera2 = new THREE.PerspectiveCamera( 110, window.innerWidth/2/window.innerHeight, 5)
camera2.position.y = 500;
var scene2 = new THREE.Scene();
var planeGeo = new THREE.PlaneGeometry(planeSize, planeSize, planeDefinition, planeDefinition);
var plane = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
color: meshColor,
wireframe: true
}));
plane.rotation.x -= Math.PI * .5;
scene2.add(plane);
function updatePlane() {
for (var i = 0; i < planeGeo.vertices.length; i++) {
planeGeo.vertices[i].z += Math.random() * vertexHeight;
planeGeo.vertices[i]._myZ = planeGeo.vertices[i].z
}
};
var count = 0
updatePlane();
//BALL ITEM
var camera = new THREE.PerspectiveCamera(100, window.innerWidth/2/window.innerHeight, 0.1, 1000);
var sceneTop = new THREE.Scene(); // initialising the scene
sceneTop.background = new THREE.Color( 0x08080c);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100,100,100);
spotLight.castShadow = false;
sceneTop.add(spotLight);
function Mat(){
var material = new THREE.MeshPhongMaterial({
color : new THREE.Color(0xff3266),
emissive : new THREE.Color(0x08080c),
specular : new THREE.Color(0x08080c),
shininess : 0,
wireframe : true,
transparent: 0.5,
opacity : 0.55
});
return material;
}
var geometry = new THREE.IcosahedronGeometry(45 , 1);
var obj = new THREE.Mesh(geometry, Mat());
sceneTop.add(obj);
camera.position.z = 90;
function myrender(){
var gridSpeed = 0.4;
var gridInterlop = -0.4;
var gridWaveSpeed = 0.003;
var gridWaveHeight = 0.00003;
for (var i = 0; i < planeGeo.vertices.length; i++) {
var z = +planeGeo.vertices[i].z;
planeGeo.vertices[i].z = Math.sin(( i + count * gridWaveHeight)) * (planeGeo.vertices[i]._myZ - (planeGeo.vertices[i]._myZ * gridWaveSpeed))
plane.geometry.verticesNeedUpdate = true;
count += gridInterlop
}
obj.rotation.x += 0.0004;
obj.rotation.y += 0.0006;
obj.rotation.z += Math.random() * 0.0005;
renderer.setViewport(0,0,window.innerWidth, window.innerHeight);
renderer.clear();
renderer.setViewport(window.innerWidth/2,0,window.innerWidth/2, window.innerHeight);
renderer.render(sceneTop, camera, 0, false);
renderer.setViewport(0,0,window.innerWidth/2, window.innerHeight);
renderer.render(scene2, camera2, 0, false);
requestAnimationFrame(myrender);
}
window.addEventListener('resize', onWindowResize, true);
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / 2 / window.innerHeight;
camera.updateProjectionMatrix();
camera2.aspect = window.innerWidth / 2 / window.innerHeight;
camera2.updateProjectionMatrix();
};
myrender();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>

create a 3D object by adding a default height javascript

I have this code which should create a 3D form. The idea is that I have whatever coordinates stored into a vector in the same plan to which I should add a default height in order to make it 3D. As you can see I am a beginner in programming and this is the first time I use ThreeJS so can you tell me what am I doing wrong? Honestly I have no clue and I would like to know if there is another way of adding the default height to my 2D vector coordinates in order to make it 3D without using ThreeJS. Thank you!
$(document).ready(function(){
function storeCoordinate(x, y, array) {
array.push(x);
array.push(y);
}
var coords = [];
var z=500;
storeCoordinate(3, 5, coords);
storeCoordinate(10, 100, coords);
storeCoordinate(30, 120, coords);
storeCoordinate(3, 5, coords);
for (var i = 0; i < coords.length; i+=2) {
var x = coords[i];
var y = coords[i+1];
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var shape = new THREE.Shape( coords );
ctx.moveTo(coords[i],coords[i+1]);
ctx.lineTo(coords[i+2],coords[i+3]);
ctx.stroke();
}
var render,mycanvas,scene,camera,renderer,light;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 1, 1000 );
var extrudedGeometry = new THREE.ExtrudeGeometry(shape, {amount: 5, bevelEnabled: false});
var extrudedMesh = new THREE.Mesh(extrudedGeometry, new THREE.MeshPhongMaterial({color: 0xff0000}));
scene.add(extrudedMesh);
document.body.onmousemove = function(e){
extrudedMesh.rotation.z = e.pageX / 100;
extrudedMesh.rotation.x = e.pageY / 100;
}
//lights
dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.intensity = .9;
dirLight.position.set(500, 140, 500);
dirLight.castShadow = true;
dirLight.shadowMapHeight = 2048
dirLight.shadowMapWidth = 2048
dirLight.shadowDarkness = .15
spotLight = new THREE.PointLight( 0xffffff );
spotLight.intensity = .5
spotLight.position.set( -500, 140, -500 );
camera.add( spotLight)
camera.add(dirLight);
lighthelper = new THREE.DirectionalLightHelper(dirLight, 20);
lighthelper.children[1].material.color.set(0,0,0)
lighthelper.visible = false;
scene.add(lighthelper);
ambientLight = new THREE.AmbientLight( 0x020202, 1 );
scene.add( ambientLight );
light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
renderer = new THREE.WebGLRenderer({canvas: mycanvas});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.enableZoom = true;
controls.enablePan = true;
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 1.0;
controls.panSpeed = 2.0;
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.minDistance = 1.1;
controls.maxDistance = 1000;
controls.keys = [65, 83, 68]; // [ rotateKey, zoomKey, panKey ]
}
function animate() {
window.requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
var loader = new THREE.OBJLoader();
});
Just an option of how you can do it, using THREE.ExtrudeGeometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 3);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var grid = new THREE.GridHelper(5, 10, "white", "gray");
grid.geometry.rotateX(Math.PI * 0.5);
scene.add(grid);
var points = [
new THREE.Vector2(0, 1),
new THREE.Vector2(1, 1),
new THREE.Vector2(1, 0)
]
var shape = new THREE.Shape(points);
var extrudeGeom = new THREE.ExtrudeGeometry(shape, {
amount: 0.5,
bevelEnabled: false
});
var mesh = new THREE.Mesh(extrudeGeom, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render)
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Javascript Three.JS Shadow Maps Not Working

I'm kinda new to Three.js, I'm enjoying it a whole bunch, though I'm having an issue with shadow maps, I've read and looked everywhere but I just can't get it to work, can somebody point me in the direction of what I'm doing wrong?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1,1,1);
var cube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial( {color: 0x808080 } ));
cube.castShadow = true;
scene.add( cube );
camera.position.y = 2;
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 0, 10, 0 );
directionalLight.castShadow = true;
scene.add( directionalLight );
var geo2 = new THREE.BoxGeometry(5,0.1,5);
var floor = new THREE.Mesh(geo2, new THREE.MeshLambertMaterial( {color: 0x808080 } ));
floor.position.y = -1;
floor.receiveShadow = true;
scene.add(floor);
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
var ambient = new THREE.AmbientLight( 0x111111 );
directionalLight.shadowCameraVisible = true;
scene.add( ambient );
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;
function animate() {
camera.lookAt({x:0,y:0,z:0});
var timer = Date.now() * 0.0002;
camera.position.x = Math.cos(timer) * 5;
camera.position.z = Math.sin(timer) * 5;
requestAnimationFrame(animate);
render();
}
function render() {
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
animate();
These three lines:
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;
should be on your light not the renderer; so
directionalLight.shadowCameraNear = 3;
directionalLight.shadowCameraFar = camera.far;
directionalLight.shadowCameraFov = 50;
and since your light is directional you will need:
directionalLight.shadowCameraLeft = -500;
directionalLight.shadowCameraRight = 500;
directionalLight.shadowCameraTop = 500;
directionalLight.shadowCameraBottom = -500;
and you might need to play around with these values.

Categories