I'm new to three.js and I'd like to learn how to cycle through materials onclick. This example shows what I'd like to achieve except it's cycling through textures rather than materials.
I'd like to have the materials in an array, then be able to click the canvas to cycle and loop through the materials.
Here's the code for the above example:
var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
camera.position.y = 5;
camera.position.x = 5;
camera.lookAt(new THREE.Vector3(0,0,0)); // Make the camera look at the point of origin
var renderer = new THREE.WebGLRenderer({antialias:true});
var devicePixelRatio = window.devicePixelRatio || 1; // To handle high pixel density displays
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(devicePixelRatio);
document.body.appendChild( renderer.domElement );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
// instantiate a texture loader
var loader = new THREE.TextureLoader();
//allow cross origin loading
loader.crossOrigin = '';
// The textures to use
var arr = [
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_gates.jpg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_crate1.jpg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_crate2.jpg'
];
var textureToShow = 0;
// Load the first texture
// var texture = loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/MarbleSurface.jpg');
// Instantiate the material we will be using
var material = new THREE.MeshBasicMaterial();
// Instantiate a geometry to use
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
// Instatiate the mesh with the geometry and material
var cube = new THREE.Mesh( geometry, material );
cube.position.y = 0.5;
// Then load the texture
loader.load(arr[textureToShow], function(tex) {
// Once the texture has loaded
// Asign it to the material
material.map = tex;
// Update the next texture to show
textureToShow++;
// Add the mesh into the scene
scene.add( cube );
});
// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];
canvas.addEventListener("click", function() {
loader.load(arr[textureToShow], function(tex) {
// Once the texture has loaded
// Asign it to the material
material.map = tex;
// Update the next texture to show
textureToShow++;
// Have we got to the end of the textures array
if(textureToShow > arr.length-1) {
textureToShow = 0;
}
});
});
// Start rendering the scene
render();
Here's the code I can't get working:
var container, stats;
var camera, scene, renderer;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var globalObject;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 500;
//scene
scene = new THREE.Scene();
ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);
pointLight = new THREE.PointLight(0xff0000, 0.5);
pointLight.position.z = 2500;
scene.add(pointLight);
var pointLight2 = new THREE.PointLight(0xff6666, 1);
camera.add(pointLight2);
var pointLight3 = new THREE.PointLight(0x0000ff, 0.5);
pointLight3.position.x = -1000;
pointLight3.position.z = 1000;
scene.add(pointLight3);
//manager
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
//materials
var path = "textures/cube/skybox/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var reflectionCube = new THREE.CubeTextureLoader().load(urls);
var material = new THREE.MeshStandardMaterial({
envMap: reflectionCube,
roughness: 0.1,
metalness: 1,
color: 0xfee6af,
});
var materialTwo = new THREE.MeshStandardMaterial({
envMap: reflectionCube,
roughness: 0.1,
metalness: 0,
color: 0xffff00,
});
//model
var loader = new THREE.OBJLoader(manager);
loader.load('logo97.obj', function(object) {
//store global reference to .obj
globalObject = object;
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = material;
child.material.needsUpdate = true;
}
});
object.position.y = 0;
scene.add(object);
});
//render
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];
canvas.addEventListener("click", function() {
var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
child.material = materials[materialToShow];
});
//animate
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
You have to create an array of THREE.Materials:
e.g.
var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
In the "click" can change the current material of the THREE.Mesh by changing the property .material.
canvas.addEventListener("click", function() {
materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
mesh.material = materials[materialToShow];
});
Of course you have to add some light (e.g. THREE.AmbientLight, THREE.DirectionalLight) to the scne, to make the behaviour of the different materials "visible".
See the example, where I applied the suggested changes to your original code.
I used a sphere, to represent the specular highlight of the THREE.MeshPhongMaterial.
And I removed the texture, but of course you can apply the texture, too.
var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.y = 4;
camera.lookAt(new THREE.Vector3(0,0,0)); // Make the camera look at the point of origin
var renderer = new THREE.WebGLRenderer({antialias:true});
var devicePixelRatio = window.devicePixelRatio || 1; // To handle high pixel density displays
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(devicePixelRatio);
document.body.appendChild( renderer.domElement );
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,-1.0);
scene.add( directionalLight );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
var geometry = new THREE.SphereGeometry( 1, 32, 16 );
var mesh = new THREE.Mesh( geometry, materials[materialToShow] );
scene.add( mesh );
// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];
canvas.addEventListener("click", function() {
materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
mesh.material = materials[materialToShow];
});
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
// Start rendering the scene
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
Since you have used the THREE.OBJLoader, you have to change of the .material of the .children of the root object globalObject (Object3D).
Of course materialToShow and materials have to be initialized only once:
var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
canvas.addEventListener("click", function() {
materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
globalObject.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = materials[materialToShow];
child.material.needsUpdate = true;
}
});
});
See the example, where I applied the changes to your original code, with some changes to make it work in here:
var container, stats;
var camera, scene, renderer;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var globalObject;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.y = 3;
camera.position.z = 3;
//scene
scene = new THREE.Scene();
ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(0.5,2,-1.0);
scene.add( directionalLight );
pointLight = new THREE.PointLight(0xff0000, 0.5);
pointLight.position.z = 10;
scene.add(pointLight);
var pointLight2 = new THREE.PointLight(0xff6666, 1);
camera.add(pointLight2);
var pointLight3 = new THREE.PointLight(0x0000ff, 0.5);
pointLight3.position.x = -10;
pointLight3.position.z = 10;
scene.add(pointLight3);
//manager
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
//materials
/*
var path = "textures/cube/skybox/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
*/
//var reflectionCube = new THREE.CubeTextureLoader().load(urls);
var material = new THREE.MeshStandardMaterial({
//envMap: reflectionCube,
roughness: 0.1,
metalness: 1,
color: 0xfee6af,
});
var materialTwo = new THREE.MeshStandardMaterial({
//envMap: reflectionCube,
roughness: 0.1,
metalness: 0,
color: 0xffff00,
});
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
var textFile = window.URL.createObjectURL(data);
return textFile;
}
var textbox_obj = document.getElementById('plane_obj');
var obj_url = makeTextFile(textbox_obj.value);
//model
var loader = new THREE.OBJLoader(manager);
loader.load(obj_url, function(object) {
//store global reference to .obj
globalObject = object;
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = material;
child.material.needsUpdate = true;
}
});
object.position.y = 0;
scene.add(object);
});
//render
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];
var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
canvas.addEventListener("click", function() {
materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
globalObject.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = materials[materialToShow];
child.material.needsUpdate = true;
}
});
});
//animate
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
//camera.position.x += (mouseX - camera.position.x) * .05;
//camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
<textarea id="plane_obj" style="display:none;">
# Blender v2.77 (sub 0) OBJ File: 'Plane.blend'
# www.blender.org
mtllib Plane.mtl
o Plane
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vn 0.0000 1.0000 0.0000
usemtl Material
s off
f 1/1/1 2/2/1 4/4/1 3/3/1
</textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/OBJLoader.js"></script>
Related
I'm trying to create an ocean for my Three.js application. I took the example from this site:
https://codepen.io/RemiRuc/pen/gJMwOe?fbclid=IwAR2caTQL-AOPE2Gv6x4rzSWBrOmAh2j-raqesOO0XbYQAuSG37imbMszSis
var params = {
res : 32,
speed : 8,
amp : 2,
wireframe : true,
backgroundColor : 0x9c81e3,
planeColor : 0x4a4a4a
}
var scene = new THREE.Scene();
scene.background = new THREE.Color(params.backgroundColor)
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 )
let canvas = document.getElementById("webgl")
var renderer = new THREE.WebGLRenderer({canvas:canvas, antialias: true})
renderer.setSize( window.innerWidth, window.innerHeight )
var simplex = new SimplexNoise()
var light = new THREE.AmbientLight( 0xcccccc ); // soft white light
scene.add( light );
var pointLight = new THREE.PointLight( 0xeeeeee, 1, 100 );
pointLight.position.set( 0, 20, -20 );
scene.add( pointLight );
let geometry, material, plane
createPlane()
camera.position.z = 5;
camera.position.y = 3;
camera.lookAt(new THREE.Vector3( 0, 3, 0 ))
var animate = function () {
requestAnimationFrame( animate );
for (var i = 0; i < geometry.vertices.length; i++) {
var z = (i + Date.now() * params.speed/100000)
geometry.vertices[i].z = simplex.noise4D(z,z,z,z) * params.amp
plane.geometry.verticesNeedUpdate = true;
}
scene.background = new THREE.Color(params.backgroundColor)
material.color = new THREE.Color(params.planeColor)
material.wireframe = params.wireframe
camera.rotation.y += 0.001
renderer.render( scene, camera );
};
animate();
function createPlane(){
geometry = new THREE.PlaneGeometry( 200, 200, params.res,params.res );
material = new THREE.MeshLambertMaterial( {color: params.planeColor, side: THREE.DoubleSide, wireframe: params.wireframe} );
plane = new THREE.Mesh( geometry, material );
scene.add( plane );
plane.rotation.x = Math.PI/2
}
/***RESIZE***/
window.addEventListener('resize', ()=>{
document.querySelector('canvas').style.width = window.innerWidth + "px"
document.querySelector('canvas').style.height = window.innerHeight + "px"
renderer.setSize( window.innerWidth, window.innerHeight )
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
})
var gui = new dat.GUI()
var controller = gui.add(params, "res", 0, 100).name("Plane resolution")
gui.add(params, "speed", 0, 500).name("Wave speed")
gui.add(params, "amp", 0, 20).name("Wave amplitude")
gui.add(params, "wireframe", 0, 20).name("Wireframe")
gui.addColor(params, "backgroundColor").name("Background color")
gui.addColor(params, "planeColor").name("Plane color")
controller.onChange(()=>{
scene.remove(plane)
createPlane()
})
Issue is, I'm using PlaneBufferGeometry instead of PlaneGeometry, and it seems there are some differences
My code in render after creating the waterPlane
for (var i = 0; i < waterGeometry.attributes.position.count; i++) {
var z = (i + Date.now() * params.speed/100000);
waterGeometry.attributes.position[i] = simplex.noise4D(z,z,z,z) * params.amp;
}
waterGeometry.attributes.position.needsUpdate = true;
waterPlaneMesh.attributes.position.needsUpdate = true;
I'm not getting any errors, but no matter what I do, all I get is a flat wireframe plane geometry that doesn't move or anything. I think issue is in the updating of the plane?
This is an example of how you can displace vertices of a buffer geometry, using that SimplexNoise library:
body {
margin: 0;
background-color: #000;
color: #fff;
font-family: Monospace;
font-size: 13px;
line-height: 24px;
overscroll-behavior: none;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0";
import { OrbitControls } from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls";
import { createNoise3D } from "https://cdn.skypack.dev/simplex-noise";
let simplex = createNoise3D();
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 2000);
camera.position.set(0, 0.5, 1).setLength(12);
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", onWindowResize);
//scene.add(new THREE.GridHelper())
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let v3 = new THREE.Vector3();
let v2 = new THREE.Vector2();
let g = new THREE.PlaneGeometry(200, 200, 100, 100);
g.rotateX(-Math.PI *0.5);
let m = new THREE.MeshLambertMaterial({color: "aqua", wireframe: false});
let o = new THREE.Mesh(g, m);
scene.add(o);
let clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
let t = clock.getElapsedTime();
for(let i = 0; i < g.attributes.position.count; i++){
v2.fromBufferAttribute(g.attributes.uv, i).addScalar(t * 0.01).multiplyScalar(20);
let h = simplex(v2.x, v2.y, t * 0.1);
g.attributes.position.setY(i, h);
}
g.computeVertexNormals();
g.attributes.position.needsUpdate = true;
});
function onWindowResize() {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
}
</script>
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.
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>
I am trying to get the user to click on two different points and get distance between them.
The clicks seems to be happening at random positions, so the calculation is getting to be wrong.
The calculation is correct when the the OBJ loader is used and we use an OBJ file, but if I use an STL file using the STL loader, it just shows up incorrect.
Codepen link: https://codepen.io/anon/pen/NLXavX
JS Code:
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/qooungyrgltucai/three.js"></script>
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/ddt89ncslm4o7ie/Detector.js"></script>
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/mrhumrr2bxwt9nt/OBJLoader.js"></script>
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/n5sjyymajykna51/TGALoader.js"></script>
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/y4r5bmq2037jacg/OrbitControls.js"></script>
<script type="text/javascript" src="https://dl.dropboxusercontent.com/s/h18h48v52739df4/STLLoader.js"></script>
<script>
var container;
var camera, controls, scene, renderer, model;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
controls = new THREE.OrbitControls(camera);
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight(0x404040); //0x101030
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// Loading manager
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
console.log('Error: ' + xhr);
};
// Model
//model = new THREE.Object3D();
//scene.add(model);
var material = new THREE.MeshPhongMaterial({
color: 0xffffff,
needsUpdate: true
});
window.model ='';
// Added an if else here, STL code:
var loader = new THREE.STLLoader();
loader.load( 'https://dl.dropboxusercontent.com/s/t57h7xketafodui/5a9b75e521aaf-DI_PIPE_FBG_holder.stl', function ( geometry ) {
var material = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, - 0.25, 0.6 );
mesh.rotation.set( 0, - Math.PI / 2, 0 );
mesh.scale.set( 0.05, 0.05, 0.05 );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
window.model = scene;
} );
// This OBJ Loader will load if user requests an OBJ file.
var loader = new THREE.OBJLoader(manager);
var object = loader.load('https://dl.dropboxusercontent.com/s/pn3yw6w5962o5r8/BIGIPIGI.obj', function (Object) {
Object.castShadow = true;
Object.position.x = 0;
Object.position.y = -1;
Object.position.z = 0;
Object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
console.log(Object);
window.model = Object;
scene.add(Object);
}, onProgress, onError);
// Object
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousedown', onDocumentMouseDown, false);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Measurement Code
var pointA = new THREE.Vector3( 0, 1, 0 );
var pointB = new THREE.Vector3();
var markerA = new THREE.Mesh( new THREE.SphereGeometry( 0.1, 16, 16 ), new THREE.MeshBasicMaterial( { color: 0xFF5555, depthTest: false, depthWrite: false } ) );
var markerB = markerA.clone();
scene.add( markerA );
scene.add( markerB );
var line;
function getIntersections( event ) {
var vector = new THREE.Vector2();
vector.set(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1 );
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera( vector, camera );
var intersects = raycaster.intersectObjects( window.model.children );
return intersects;
}
function getLine( vectorA, vectorB ) {
var geometry = new THREE.Geometry();
geometry.vertices.push( vectorA );
geometry.vertices.push( vectorB );
var material = new THREE.LineBasicMaterial({
color: 0xFFFF00,
depthWrite: false,
depthTest: false
});
line = new THREE.Line( geometry, material );
return line;
}
function onDocumentMouseDown( event ) {
var intersects = getIntersections( event );
if( intersects.length > 0 ){
if ( ! pointB.equals( pointA ) ) {
pointB = intersects[ 0 ].point;
} else {
pointB = pointA;
}
pointA = intersects[ 0 ].point;
markerA.position.copy( pointA );
markerB.position.copy( pointB );
var distance = pointA.distanceTo( pointB );
if ( line instanceof THREE.Line ) {
scene.remove( line );
}
if ( distance > 0 ) {
console.log( "distance", distance );
alert( "distance: "+distance );
line = getLine( pointA, pointB );
scene.add(line);
}
}
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}</script>
Try to add in CSS section:
body{
overflow: hidden;
margin: 0;
}
How to show a cube map reflection on a object without showing the cubemap in the background?
I like to receive a reflection on a lever mechanism without showing a cubemap in the background. The background should be with a gradient from blue to white.
So basicially, the cubemap should be only visible on the object.
Thank you very much in advance!
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var loader;
var camera, cameraTarget, controls, scene, renderer;
init();
animate();
function init() {
var previewDiv = document.getElementById("preview");
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( 3, 0.15, 3 );
cameraTarget = new THREE.Vector3( 0, -0.25, 0 );
controls = new THREE.OrbitControls( camera );
controls.maxPolarAngle = Math.PI / 2.2;
controls.minDistance = 3;
controls.maxDistance = 8;
// controls.noPan = true;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xdae1e6, 2, 15 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 40, 40 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// feinleinen
var feinleinen = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' );
feinleinen.anisotropy = 1;
feinleinen.wrapS = feinleinen.wrapT = THREE.RepeatWrapping;
feinleinen.repeat.set( 5, 5 );
// create a cube
var basisGeometry = new THREE.BoxGeometry(3,0.02,3);
var basisMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinen } );
var basis = new THREE.Mesh(basisGeometry, basisMaterial);
basis.castShadow = false;
basis.receiveShadow = true;
// position the cube
basis.position.set( 0, -0.47, 0 );
// add the cube to the scene
scene.add(basis);
var loader = new THREE.JSONLoader();
loader.load('/models/hebelmechanik.js', function(geo, mat){
var chrome = new THREE.MeshLambertMaterial( { ambient: 0x444444, color: 0x111111, shininess: 800, specular: 0x111111, shading: THREE.SmoothShading, reflectivity: 1.1 } );
var mesh = new THREE.Mesh(geo, chrome);
mesh.position.set( 0, - 0.497, 0 );
mesh.rotation.set( 0, - Math.PI / 2, 0 );
mesh.scale.set( 0.008, 0.008, 0.008 );
mesh.castShadow = true;
mesh.receiveShadow = true;
loadJson(mesh );
});
function loadJson(mesh){
scene.add( mesh );
}
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffffff, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
previewDiv.appendChild (renderer.domElement);
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.lookAt( cameraTarget );
controls.update();
renderer.render( scene, camera );
}
</script>
You can add a cubemap reflection to your model by specifying the envMap property of the model's material.
Use a pattern like this one:
var path = "textures/cube/foo/";
var format = '.png';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var envMap = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping, callback ); // callback function is optional
var material = new THREE.MeshPhongMaterial( {
color : 0x999999,
specular : 0x050505,
shininess : 50,
envMap : envMap,
combine : THREE.MixOperation, // or THREE.AddOperation, THREE.MultiplyOperation
reflectivity : 0.5
} );
three.js r.71