I am using this tutorial to load .obj and .material files in webgl using three.js - https://manu.ninja/webgl-3d-model-viewer-using-three-js
i just changed the assets but it doesn't show the new assets in chrome.
I also run local server to load assets from directory and also did --allow-file-access-from-files but still it doesn't show new obj and material files
Here's my code -
<!DOCTYPE html>
<title>WebGL 3D Model Viewer Using three.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="three.js"></script>
<script src="Detector.js"></script>
<script src="OrbitControls.js"></script>
<script src="OBJLoader.js"></script>
<script src="MTLLoader.js"></script>
<script>
if (!Detector.webgl) {
Detector.addGetWebGLMessage();
}
var container;
var camera, controls, scene, renderer;
var lighting, ambient, keyLight, fillLight, backLight;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
/* Camera */
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 3;
/* Scene */
scene = new THREE.Scene();
lighting = false;
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
/* Model */
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('SYDNEY.mtl', function (materials) {
materials.preload();
materials.materials.default.map.magFilter = THREE.NearestFilter;
materials.materials.default.map.minFilter = THREE.LinearFilter;
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('SYDNEY.obj', function (object) {
scene.add(object);
});
});
/* Renderer */
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("hsl(0, 0%, 10%)"));
container.appendChild(renderer.domElement);
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
/* Events */
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('keydown', onKeyboardEvent, 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 onKeyboardEvent(e) {
if (e.code === 'KeyL') {
lighting = !lighting;
if (lighting) {
ambient.intensity = 0.25;
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
} else {
ambient.intensity = 1.0;
scene.remove(keyLight);
scene.remove(fillLight);
scene.remove(backLight);
}
}
}
function animate() {
requestAnimationFrame(animate);
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
Am i missing here something?
Related
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 am trying to create something like on this photo
So, how to remove that strange lines from the model
http://weblife.su/WineBazar/1/
You can see those lines while rorating the model.
What is the problem? I need to use opacity, to get result like on that scrinshot.
At least, can I hide the background for user, but reflectivity and metalness will be on my model?
My threeJs script is here
Thank you for the help!
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js';
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js';
import { RGBELoader } from 'https://threejs.org/examples/jsm/loaders/RGBELoader.js';
import { RoughnessMipmapper } from 'https://threejs.org/examples/jsm/utils/RoughnessMipmapper.js';
var container, controls;
var camera, scene, renderer;
init();
render();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 20);
camera.position.set(-1.8, 0.6, 2.7);
scene = new THREE.Scene();
new RGBELoader()
.setDataType(THREE.UnsignedByteType)
.setPath('https://threejs.org/examples/textures/equirectangular/')
.load('royal_esplanade_1k.hdr', function(texture) {
var envMap = pmremGenerator.fromEquirectangular(texture).texture;
scene.background = envMap;
scene.environment = envMap;
texture.dispose();
pmremGenerator.dispose();
render();
// model
// use of RoughnessMipmapper is optional
var roughnessMipmapper = new RoughnessMipmapper(renderer);
var loader = new GLTFLoader()
loader.load('http://weblife.su/WineBazar/1/ws_r_2-5.glb', function(gltf) {
gltf.scene.traverse(function(child) {
if (child.isMesh) {
child.material.color.setHex(0x9ed7f5);
child.material.emissive.setHex(0x062f61);
child.material.transparent = true;
child.material.opacity = 0.5;
child.material.needsUpdate = true;
child.material.reflectivity = 0.8;
child.material.roughness = 0.2;
child.material.metalness = 0.5;
child.depthWrite = true;
}
});
scene.add(gltf.scene);
roughnessMipmapper.dispose();
render();
});
});
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild(renderer.domElement);
var pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render); // use if there is no animation loop
controls.minDistance = 2;
controls.maxDistance = 32;
controls.target.set(0, 0, -0.2);
controls.update();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
//
function render() {
renderer.render(scene, camera);
}
</script>
Looks like self-transparency artifacts. You should always set depthWrite to false if you encounter such rendering problems. But even this setting might not help to remove all glitches since correctly rendering transparency is very tricky. You would need a special Order-independent transparency algorithm like depth-peeling which is not supported by three.js.
https://en.wikipedia.org/wiki/Order-independent_transparency
Related issue at GitHub: https://github.com/mrdoob/three.js/issues/9977
this is what i want to do.Once you click on the box then i want to appear a second box and when i click on the second box i want the color from the first cube to change.I manage to make the first step but i don't know how to implement the last step, to click on the second cube and then change the color of my original.Here is my code...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
1000
);
camera.position.z = 2;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
material = new THREE.MeshLambertMaterial({ color: 0x2c9b73 });
mesh = new THREE.Mesh(geometry, material);
mesh.rotation.set(45, 0, 0);
scene.add(mesh);
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 10, 10);
scene.add(light);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("#e5e5e5");
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
}
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children, true);
for (var i = 0; i < intersects.length; i++) {
var geometry1 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var material1 = new THREE.MeshLambertMaterial({ color: 0xce2121 });
var mesh1 = new THREE.Mesh(geometry1, material1);
mesh1.position.y = 1;
scene.add(mesh1);
}
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
//mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
window.addEventListener("click", onMouseMove);
</script>
</body>
</html>
First, you can name your mesh.
For say, we can name it as rotatingMesh & staticMesh.
Naming is required to track on which 3d obj click event is being performed.
Now if I Click on the second cube should turn to yellow, for that you have to listen for click on the 2nd object also (as shown below)
for (var i = 0; i < intersects.length; i++) {
if(intersects[i].object.name === 'staticMesh') {
// Set rotating mesh color to yellow
mesh.material.color = new THREE.Color(1,1,0)
} else {
var geometry1 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var material1 = new THREE.MeshLambertMaterial({ color: 0xce2121 });
var mesh1 = new THREE.Mesh(geometry1, material1);
mesh1.name = 'staticMesh'
mesh1.position.y = 1;
scene.add(mesh1);
}
}
Have shown the use case in the below code snippet.
Kindly let me know if you have any other doubt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
1000
);
camera.position.z = 2;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
material = new THREE.MeshLambertMaterial({ color: 0x2c9b73 });
mesh = new THREE.Mesh(geometry, material);
mesh.name = 'rotatingMesh'
mesh.rotation.set(45, 0, 0);
scene.add(mesh);
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 10, 10);
scene.add(light);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("#e5e5e5");
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
}
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children, true);
for (var i = 0; i < intersects.length; i++) {
if(intersects[i].object.name === 'staticMesh') {
// Set rotating mesh color to yellow
mesh.material.color = new THREE.Color(1,1,0)
} else {
var geometry1 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var material1 = new THREE.MeshLambertMaterial({ color: 0xce2121 });
var mesh1 = new THREE.Mesh(geometry1, material1);
mesh1.name = 'staticMesh'
mesh1.position.y = 1;
scene.add(mesh1);
}
}
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
//mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
window.addEventListener("click", onMouseMove);
</script>
</body>
</html>
I am trying to display a 3D .obj model in a webpage using three.js. The model is an obj file. I can see the model using the three.js script but it has a weird while color.
The original model looks like Original. (Used a 3D viewer to upload the obj file). But the output I am getting is totally white. three.js
<script>
if (!Detector.webgl) {
Detector.addGetWebGLMessage();
}
var container;
var camera, controls, scene, renderer;
var lighting, ambient, keyLight, fillLight, backLight;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
/* Camera */
camera = new THREE.PerspectiveCamera(45, window.innerWidth /window.innerHeight, 1, 90000000000);
camera.position.z = 4000;
/* Scene */
scene = new THREE.Scene();
lighting = false;
ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 10%, 7%)'), 1.0);
keyLight.position.set(-100, 0, 100);
fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 10%, 7%)'), 0.75);
fillLight.position.set(100, 0, 100);
backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
/* Model */
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('caster/');
mtlLoader.setPath('caster/');
mtlLoader.load('edger-QLgame.mtl', function (materials) {
materials.preload();
//materials.materials.default.map.magFilter = THREE.NearestFilter;
//materials.materials.default.map.minFilter = THREE.LinearFilter;
var objLoader = new THREE.OBJLoader();
//objLoader.setMaterials(materials);
mtlLoader.setBaseUrl('caster/');
objLoader.setPath('caster/');
objLoader.load('edger-QLgame.obj', function (object) {
scene.add(object);
});
});
/* Renderer */
renderer = new THREE.WebGLRenderer();
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("hsl(0, 0%, 10%)"));
renderer.gammaOutput = true;
container.appendChild(renderer.domElement);
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
/* Events */
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('keydown', onKeyboardEvent, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onKeyboardEvent(e) {
if (e.code === 'KeyL') {
lighting = !lighting;
if (lighting) {
ambient.intensity = 0.25;
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
} else {
ambient.intensity = 1.0;
scene.remove(keyLight);
scene.remove(fillLight);
scene.remove(backLight);
}
}
}
function animate() {
requestAnimationFrame(animate);
controls.update();
render();
}
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
function render() {
renderer.render(scene, camera);
}
function onDocumentMouseWheel( event ) {
var fovMAX = 160;
var fovMIN = 1;
camera.fov -= event.wheelDeltaY * 0.05;
camera.fov = Math.max( Math.min( camera.fov, fovMAX ), fovMIN );
camera.projectionMatrix = new THREE.Matrix4().makePerspective(camera.fov, window.innerWidth / window.innerHeight, camera.near, camera.far);
}
I have a scene which have several objects, and i want to click and select an object, and rotate and zoom the scene.
For zoom, rotate and pan the scene, i use TrackballControl.js.
For click and select and object, i use Projector.js.
They work separately as i want. But when i combine both Projector.js doesn't work because of the TrackballControl. I don't know how to use these two together.
Do you have any suggestion for me?
My test code is below:
<!DOCTYPE html>
<html>
<head>
<title>Selecting objects</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/Projector.js"></script>
<script type="text/javascript" src="../libs/TrackballControls.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="WebGL-output">
</div>
<script type="text/javascript">
var scene, camera,renderer,cube,sphere,cylinder, control;
function prepareScene(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.set(-30,40,30);
camera.lookAt(scene.position);
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
scene.add(spotLight);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
}
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function addGeometry(){
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-9,3,0);
scene.add(cube);
}
function animate() {
requestAnimationFrame(animate);
control.update();
}
function onDocumentMouseDown(event) {
var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
vector = vector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects([cube]);
if (intersects.length > 0) {
console.log(intersects[0].point);
intersects[0].object.material.transparent = true;
intersects[0].object.material.opacity = 0.1;
}
}
function init() {
prepareScene();
var projector = new THREE.Projector();
document.addEventListener('mousedown', onDocumentMouseDown, false);
/*control = new THREE.TrackballControls(camera, document.getElementById("WebGL-output"));
control.addEventListener("change", render);
control.rotateSpeed = 3.0;
control.zoomSpeed = 3.0;
control.panSpeed = 3.0; */
addGeometry();
render();
//animate();
}
window.onload = init;
</script>
</body>
</html>