Three.js collision detection - javascript
I think I'm missing something very basic, but I can't find an answer, nor in documentation or other, working codes.
I'm making something like a basic museum using THREE.js libraries. I've set up most stuff, but I want to give the camera a collision. I made it like that :
var d = camera.position.distanceTo( plane_8.position );
if ( d < 200 )
{
camera.position = previousPosition;
camera.rotation = previousRotation;
}
Simple, but should work, at least against one wall. But it doesn't. What have I forgotten ?
Full code:
<html>
<head>
<title>#10 - WebGL - Three.js</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/THREEx.KeyboardState.js"></script>
<script>
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 4096 );
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
camera.position.set(0,0,1900);
scene.fog = new THREE.Fog( 0x555555, 2048, 4096 );
//=================================================================
var texture = THREE.ImageUtils.loadTexture('img/grass.jpg');
texture.repeat.set( 7,7);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = 16;
var textureW = THREE.ImageUtils.loadTexture('img/Brickwall.jpg');
textureW.repeat.set( 1,1);
textureW.wrapS = THREE.RepeatWrapping;
textureW.wrapT = THREE.RepeatWrapping;
textureW.anisotropy = 16;
var textureS = THREE.ImageUtils.loadTexture('img/styropian.jpeg');
textureS.repeat.set( 1,1);
textureS.wrapS = THREE.RepeatWrapping;
textureS.wrapT = THREE.RepeatWrapping;
textureS.anisotropy = 16;
//Mona Lisa
var textureM = THREE.ImageUtils.loadTexture('img/MonaLisa.jpg');
textureM.anisotropy = 16;
var planeMaterialM = new THREE.MeshPhongMaterial({map: textureM});
var planeGeometryM = new THREE.PlaneGeometry(385, 577);
var planeM = new THREE.Mesh( planeGeometryM, planeMaterialM );
planeM.position.x -= 500;
planeM.position.z -= 1000;
scene.add( planeM );
var planeMaterial = new THREE.MeshPhongMaterial({map: texture});
var planeGeometry = new THREE.PlaneGeometry(8192, 8192);
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.rotation.x = - Math.PI / 2;
plane.position.y -= 512;
plane.position.z -= 512;
scene.add( plane );
var planeMaterial_2 = new THREE.MeshPhongMaterial({color: 0x999999});
var planeGeometry_2= new THREE.CubeGeometry( 8192, 8, 4096 );
var plane_2 = new THREE.Mesh( planeGeometry_2, planeMaterial_2 );
plane_2.position.y += 512;
plane_2.position.z += 1024;
scene.add( plane_2 );
var planeMaterial_3 = new THREE.MeshPhongMaterial({map:textureW});
var planeGeometry_3= new THREE.CubeGeometry( 4096, 1024, 8 );
var plane_3 = new THREE.Mesh( planeGeometry_3, planeMaterial_3 );
plane_3.position.z -= 1024;
scene.add( plane_3 );
var planeMaterial_4 = new THREE.MeshPhongMaterial({map:textureW});
var planeGeometry_4= new THREE.CubeGeometry( 60,1024,2048 );
var plane_4 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
plane_4.position.x -= 2048;
scene.add( plane_4 );
var plane_5 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
plane_5.position.x -= 1024;
scene.add( plane_5);
var plane_6 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
plane_6.position.x -= 0;
scene.add( plane_6);
var plane_7 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
plane_7.position.x += 1024;
scene.add( plane_7);
var plane_8 = new THREE.Mesh( planeGeometry_4, planeMaterial_4 );
plane_8.position.x += 2048;
scene.add( plane_8);
var planeMaterial_C = new THREE.MeshPhongMaterial({map:textureW});
var planeGeometry_C= new THREE.CubeGeometry( 5120, 1024, 60 );
var plane_C = new THREE.Mesh( planeGeometry_C, planeMaterial_C );
plane_C.position.z =+ 2048;
plane_C.position.x =+ 512;
scene.add( plane_C );
var cubeGeometry = new THREE.CubeGeometry(50,50,50,1,1,1);
var wireMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true } );
MovingCube = new THREE.Mesh( cubeGeometry, wireMaterial );
MovingCube.position.set(0, -100, 1900);
scene.add( MovingCube );
var light = new THREE.AmbientLight( 0x101020 );
scene.add(light);
var pointLight = new THREE.PointLight( 0xffffff, 1, 2048 );
pointLight.position.set( -512, 0, -512 );
scene.add( pointLight );
var pointLight2 = new THREE.PointLight( 0xffffff, 1, 3000 );
pointLight2.position.set( 0, 0, 1536 );
scene.add( pointLight2 );
var pointLight3 = new THREE.PointLight( 0xffffff, 1, 2048 );
pointLight3.position.set( 512, 0, -512 );
scene.add( pointLight3 );
var kat=0;
var katL=0;
function render() {
requestAnimationFrame(render);
kat += 0.02;
katL += 0.07;
var delta = clock.getDelta();
var moveDistance = 700 * delta;
var rotateAngle = Math.PI / 3.5 * delta;
var previousPosition = camera.position.clone();
var previousRotation = camera.rotation.clone();
if ( keyboard.pressed("W") )
camera.translateZ( -moveDistance );
if ( keyboard.pressed("S") )
camera.translateZ( moveDistance );
if ( keyboard.pressed("Q") )
camera.translateX( -moveDistance );
if ( keyboard.pressed("E") )
camera.translateX( moveDistance );
if ( keyboard.pressed("A") )
camera.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
if ( keyboard.pressed("D") )
camera.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
var d = camera.position.distanceTo( plane_8.position );
if ( d < 200 )
{
camera.position = previousPosition;
camera.rotation = previousRotation;
}
renderer.render(scene, camera);
}
render();
</script>
</body>
I'm currently developing collisions for my project. Try using raycasts. My player (which i can cantrol by WSAD and mouse) emmits raycasts and check wheater they hits any objects.
Part of the code:
this.update = function (timestamp) {
if (!this.enabled) return;
if (this.hitTest) {
this.doHitTest();
}
camera.quaternion.multiplyQuaternions(this.angleQuaternion, camera.quaternion);
setFromQuaternionYComponent(this.object.quaternion, camera.quaternion);
var delta = (timestamp - lastTimestamp) / 1000;
lastTimestamp = timestamp;
var actualMoveSpeed = delta * this.movementSpeed;
if (this.moveForward && !lockMoveForward) this.object.translateZ(-actualMoveSpeed);
if (this.moveBackward && !lockMoveBackward) this.object.translateZ(actualMoveSpeed);
if (this.moveLeft && !lockMoveLeft) this.object.translateX(-actualMoveSpeed);
if (this.moveRight && !lockMoveRight) this.object.translateX(actualMoveSpeed);
if (this.verticalMovement && this.moveUp) this.object.translateY(actualMoveSpeed);
if (this.verticalMovement && this.moveDown) this.object.translateY(-actualMoveSpeed);
var hasPosition = this.sensor && this.sensor.getState().hasPosition;
var vrCameraPosition;
if (hasPosition) {
vrCameraPosition = camera.position.clone();
vrCameraPosition.applyQuaternion(this.angleQuaternion);
}
if (hasPosition) {
camera.position.add(vrCameraPosition);
} else {
//camera.position.copy(this.object.position);
camera.position.set(this.object.position.x, camera.position.y, this.object.position.z);
}
};
this.doHitTest = function () {
this.unlockAllDirections();
var hitObjects = [];
var cameraDirection = this.getDirection2(new THREE.Vector3(0, 0, 0)).clone();
for (var i = 0; i < 4; i++) {
// Applying rotation for each direction:
var direction = cameraDirection.clone();
direction.applyMatrix4(rotationMatrices[i]);
var rayCaster = new THREE.Raycaster(camera.position, direction);
var intersects = rayCaster.intersectObjects(this.hitMeshesArray, true);
if ((intersects.length > 0 && intersects[0].distance < hitTestDistance)) {
this.lockDirectionByIndex(i);
hitObjects.push(intersects[0]);
// console.log(intersects[0].object.name, i);
}
}
return hitObjects;
};
this.getDirection2 = function (v) {
var direction = new THREE.Vector3(0, 0, -1);
var rotation = new THREE.Euler(0, 0, 0, "YXZ");
var rx = camera.rotation.x;
var ry = camera.rotation.y;
// console.log("DIRECTION:", this);
rotation.set(rx, ry, 0);
v.copy(direction).applyEuler(rotation);
// console.log(v);
return v;
};
Try putting all on jsbin or simillar so we can check it.
Related
How to add Threejs Object inside a vue code or add vue model inside threejs background
Dear Stackoverflow users :) i need help to add trois model([https://codepen.io/soju22/pen/JjEqebK][1]) import { createApp } from 'https://unpkg.com/vue#3.0.11/dist/vue.esm-browser.prod.js' import { lerp, BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass } from 'https://unpkg.com/troisjs#0.3.0-beta.4/build/trois.module.cdn.min.js' import { Clock, Color, MathUtils, Vector3 } from 'https://unpkg.com/three#0.127.0/build/three.module.js' const niceColors = [["#69d2e7","#a7dbd8","#e0e4cc","#f38630","#fa6900"],["#fe4365","#fc9d9a","#f9cdad","#c8c8a9","#83af9b"],["#ecd078","#d95b43","#c02942","#542437","#53777a"],["#556270","#4ecdc4","#c7f464","#ff6b6b","#c44d58"],["#774f38","#e08e79","#f1d4af","#ece5ce","#c5e0dc"],["#e8ddcb","#cdb380","#036564","#033649","#031634"],["#490a3d","#bd1550","#e97f02","#f8ca00","#8a9b0f"],["#594f4f","#547980","#45ada8","#9de0ad","#e5fcc2"],["#00a0b0","#6a4a3c","#cc333f","#eb6841","#edc951"],["#e94e77","#d68189","#c6a49a","#c6e5d9","#f4ead5"],["#3fb8af","#7fc7af","#dad8a7","#ff9e9d","#ff3d7f"],["#d9ceb2","#948c75","#d5ded9","#7a6a53","#99b2b7"],["#ffffff","#cbe86b","#f2e9e1","#1c140d","#cbe86b"],["#efffcd","#dce9be","#555152","#2e2633","#99173c"],["#343838","#005f6b","#008c9e","#00b4cc","#00dffc"],["#413e4a","#73626e","#b38184","#f0b49e","#f7e4be"],["#ff4e50","#fc913a","#f9d423","#ede574","#e1f5c4"],["#99b898","#fecea8","#ff847c","#e84a5f","#2a363b"],["#655643","#80bca3","#f6f7bd","#e6ac27","#bf4d28"],["#00a8c6","#40c0cb","#f9f2e7","#aee239","#8fbe00"],["#351330","#424254","#64908a","#e8caa4","#cc2a41"],["#554236","#f77825","#d3ce3d","#f1efa5","#60b99a"],["#5d4157","#838689","#a8caba","#cad7b2","#ebe3aa"],["#8c2318","#5e8c6a","#88a65e","#bfb35a","#f2c45a"],["#fad089","#ff9c5b","#f5634a","#ed303c","#3b8183"],["#ff4242","#f4fad2","#d4ee5e","#e1edb9","#f0f2eb"],["#f8b195","#f67280","#c06c84","#6c5b7b","#355c7d"],["#d1e751","#ffffff","#000000","#4dbce9","#26ade4"],["#1b676b","#519548","#88c425","#bef202","#eafde6"],["#5e412f","#fcebb6","#78c0a8","#f07818","#f0a830"],["#bcbdac","#cfbe27","#f27435","#f02475","#3b2d38"],["#452632","#91204d","#e4844a","#e8bf56","#e2f7ce"],["#eee6ab","#c5bc8e","#696758","#45484b","#36393b"],["#f0d8a8","#3d1c00","#86b8b1","#f2d694","#fa2a00"],["#2a044a","#0b2e59","#0d6759","#7ab317","#a0c55f"],["#f04155","#ff823a","#f2f26f","#fff7bd","#95cfb7"],["#b9d7d9","#668284","#2a2829","#493736","#7b3b3b"],["#bbbb88","#ccc68d","#eedd99","#eec290","#eeaa88"],["#b3cc57","#ecf081","#ffbe40","#ef746f","#ab3e5b"],["#a3a948","#edb92e","#f85931","#ce1836","#009989"],["#300030","#480048","#601848","#c04848","#f07241"],["#67917a","#170409","#b8af03","#ccbf82","#e33258"],["#aab3ab","#c4cbb7","#ebefc9","#eee0b7","#e8caaf"],["#e8d5b7","#0e2430","#fc3a51","#f5b349","#e8d5b9"],["#ab526b","#bca297","#c5ceae","#f0e2a4","#f4ebc3"],["#607848","#789048","#c0d860","#f0f0d8","#604848"],["#b6d8c0","#c8d9bf","#dadabd","#ecdbbc","#fedcba"],["#a8e6ce","#dcedc2","#ffd3b5","#ffaaa6","#ff8c94"],["#3e4147","#fffedf","#dfba69","#5a2e2e","#2a2c31"],["#fc354c","#29221f","#13747d","#0abfbc","#fcf7c5"],["#cc0c39","#e6781e","#c8cf02","#f8fcc1","#1693a7"],["#1c2130","#028f76","#b3e099","#ffeaad","#d14334"],["#a7c5bd","#e5ddcb","#eb7b59","#cf4647","#524656"],["#dad6ca","#1bb0ce","#4f8699","#6a5e72","#563444"],["#5c323e","#a82743","#e15e32","#c0d23e","#e5f04c"],["#edebe6","#d6e1c7","#94c7b6","#403b33","#d3643b"],["#fdf1cc","#c6d6b8","#987f69","#e3ad40","#fcd036"],["#230f2b","#f21d41","#ebebbc","#bce3c5","#82b3ae"],["#b9d3b0","#81bda4","#b28774","#f88f79","#f6aa93"],["#3a111c","#574951","#83988e","#bcdea5","#e6f9bc"],["#5e3929","#cd8c52","#b7d1a3","#dee8be","#fcf7d3"],["#1c0113","#6b0103","#a30006","#c21a01","#f03c02"],["#000000","#9f111b","#b11623","#292c37","#cccccc"],["#382f32","#ffeaf2","#fcd9e5","#fbc5d8","#f1396d"],["#e3dfba","#c8d6bf","#93ccc6","#6cbdb5","#1a1f1e"],["#f6f6f6","#e8e8e8","#333333","#990100","#b90504"],["#1b325f","#9cc4e4","#e9f2f9","#3a89c9","#f26c4f"],["#a1dbb2","#fee5ad","#faca66","#f7a541","#f45d4c"],["#c1b398","#605951","#fbeec2","#61a6ab","#accec0"],["#5e9fa3","#dcd1b4","#fab87f","#f87e7b","#b05574"],["#951f2b","#f5f4d7","#e0dfb1","#a5a36c","#535233"],["#8dccad","#988864","#fea6a2","#f9d6ac","#ffe9af"],["#2d2d29","#215a6d","#3ca2a2","#92c7a3","#dfece6"],["#413d3d","#040004","#c8ff00","#fa023c","#4b000f"],["#eff3cd","#b2d5ba","#61ada0","#248f8d","#605063"],["#ffefd3","#fffee4","#d0ecea","#9fd6d2","#8b7a5e"],["#cfffdd","#b4dec1","#5c5863","#a85163","#ff1f4c"],["#9dc9ac","#fffec7","#f56218","#ff9d2e","#919167"],["#4e395d","#827085","#8ebe94","#ccfc8e","#dc5b3e"],["#a8a7a7","#cc527a","#e8175d","#474747","#363636"],["#f8edd1","#d88a8a","#474843","#9d9d93","#c5cfc6"],["#046d8b","#309292","#2fb8ac","#93a42a","#ecbe13"],["#f38a8a","#55443d","#a0cab5","#cde9ca","#f1edd0"],["#a70267","#f10c49","#fb6b41","#f6d86b","#339194"],["#ff003c","#ff8a00","#fabe28","#88c100","#00c176"],["#ffedbf","#f7803c","#f54828","#2e0d23","#f8e4c1"],["#4e4d4a","#353432","#94ba65","#2790b0","#2b4e72"],["#0ca5b0","#4e3f30","#fefeeb","#f8f4e4","#a5b3aa"],["#4d3b3b","#de6262","#ffb88c","#ffd0b3","#f5e0d3"],["#fffbb7","#a6f6af","#66b6ab","#5b7c8d","#4f2958"],["#edf6ee","#d1c089","#b3204d","#412e28","#151101"],["#9d7e79","#ccac95","#9a947c","#748b83","#5b756c"],["#fcfef5","#e9ffe1","#cdcfb7","#d6e6c3","#fafbe3"],["#9cddc8","#bfd8ad","#ddd9ab","#f7af63","#633d2e"],["#30261c","#403831","#36544f","#1f5f61","#0b8185"],["#aaff00","#ffaa00","#ff00aa","#aa00ff","#00aaff"],["#d1313d","#e5625c","#f9bf76","#8eb2c5","#615375"],["#ffe181","#eee9e5","#fad3b2","#ffba7f","#ff9c97"],["#73c8a9","#dee1b6","#e1b866","#bd5532","#373b44"],["#805841","#dcf7f3","#fffcdd","#ffd8d8","#f5a2a2"]] const { randFloat: rnd, randInt, randFloatSpread: rndFS } = MathUtils const vertexShader = ` uniform float uTime; attribute vec3 color; attribute float size; attribute float velocity; varying vec4 vColor; void main(){ vColor = vec4(color, 1.0); vec3 p = vec3(position); p.z = -150. + mod(position.z + uTime, 300.); vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 ); gl_PointSize = size * (-50.0 / mvPosition.z); gl_Position = projectionMatrix * mvPosition; } ` const fragmentShader = ` uniform sampler2D uTexture; varying vec4 vColor; void main() { gl_FragColor = vColor * texture2D(uTexture, gl_PointCoord); } ` createApp({ template: ` <Renderer ref="renderer" pointer resize="window"> <Camera :position="{ z: 0 }" :fov="35" /> <Scene> <Points ref="points" :position="{ z: -100 }"> <BufferGeometry :attributes="attributes" /> <ShaderMaterial :blending="2" :depth-test="false" :uniforms="uniforms" :vertex-shader="vertexShader" :fragment-shader="fragmentShader"> <Texture src="https://assets.codepen.io/33787/sprite.png" uniform="uTexture" /> </ShaderMaterial> </Points> </Scene> <EffectComposer> <RenderPass /> <UnrealBloomPass :strength="2" :radius="0" :threshold="0" /> <ZoomBlurPass :strength="zoomStrength" /> </EffectComposer> </Renderer> Surprise! `, components: { BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass }, setup() { const POINTS_COUNT = 50000 const palette = niceColors[23] const positions = new Float32Array(POINTS_COUNT * 3) const colors = new Float32Array(POINTS_COUNT * 3) const sizes = new Float32Array(POINTS_COUNT) const v3 = new Vector3(), color = new Color() for (let i = 0; i < POINTS_COUNT; i++) { v3.set(rndFS(200), rndFS(200), rndFS(300)) v3.toArray(positions, i * 3) color.set(palette[Math.floor(rnd(0, palette.length))]) color.toArray(colors, i * 3) sizes[i] = rnd(5, 20) } const attributes = [ { name: 'position', array: positions, itemSize: 3 }, { name: 'color', array: colors, itemSize: 3 }, { name: 'size', array: sizes, itemSize: 1 }, ] const uniforms = { uTime: { value: 0 } } const clock = new Clock() const timeCoef = 1, targetTimeCoef = 1 return { POINTS_COUNT, attributes, uniforms, vertexShader, fragmentShader, clock, timeCoef, targetTimeCoef, } }, data() { return { zoomStrength: 0, } }, mounted() { const renderer = this.$refs.renderer const positionN = renderer.three.pointer.positionN const points = this.$refs.points.points renderer.onBeforeRender(() => { this.timeCoef = lerp(this.timeCoef, this.targetTimeCoef, 0.02) this.uniforms.uTime.value += this.clock.getDelta() * this.timeCoef * 4 this.zoomStrength = this.timeCoef * 0.004 const da = 0.05 const tiltX = lerp(points.rotation.x, positionN.y * da, 0.02) const tiltY = lerp(points.rotation.y, -positionN.x * da, 0.02) points.rotation.set(tiltX, tiltY, 0) }) }, methods: { updateColors() { const colorAttribute = this.$refs.points.geometry.attributes.color const ip = randInt(0, 99); const palette = niceColors[ip]; const color = new Color() for (let i = 0; i < this.POINTS_COUNT; i++) { color.set(palette[randInt(0, palette.length)]) color.toArray(colorAttribute.array, i * 3) } colorAttribute.needsUpdate = true }, }, }).mount('#app') </script> <script type="module"> /** * #file * The main scene. */ /** * Define constants. */ const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/'; /** * Create the animation request. */ if (!window.requestAnimationFrame) { window.requestAnimationFrame = (function() { return window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || window.webkitRequestAnimationFrame || function (callback, element) { // 60 FPS window.setTimeout(callback, 1000 / 60); }; })(); } /** * Set our global variables. */ var camera, scene, renderer, effect, controls, element, earthy, sphere, sphereCloud, rotationPoint; var degreeOffset = 90; var earthRadius = 80; var getEarthRotation = function() { // Get the current time. var d = new Date(); var h = d.getUTCHours(); var m = d.getUTCMinutes(); // Calculate total minutes. var minutes = h * 60; minutes += m; // Turn minutes into degrees. degrees = minutes/3.9907; // Add an offset to match UTC time. degrees += degreeOffset; return degrees; } var degrees = getEarthRotation(); // Calculate Earth's rotation position. setInterval(function() { // Get the current time. var d = new Date(); var h = d.getUTCHours(); var m = d.getUTCMinutes(); // Calculate total minutes. var minutes = h * 60; minutes += m; // Turn minutes into degrees. degrees = minutes/3.9907; // Add an offset to match UTC time. degrees += degreeOffset; }, 60000); init(); animate(); var string = ''; /** * Initializer function. */ function init() { // Build the earthy = document.createElement( 'div' ); document.body.appendChild( earthy ); // Create the scene. scene = new THREE.Scene(); // Create a rotation point. baseRotationPoint = new THREE.Object3D(); baseRotationPoint.position.set( 0, 0, 0 ); scene.add( baseRotationPoint ); // Create world rotation point. worldRotationPoint = new THREE.Object3D(); worldRotationPoint.position.set( 0, 0, 0 ); scene.add( worldRotationPoint ); rotationPoint = new THREE.Object3D(); rotationPoint.position.set( 0, 0, earthRadius * 4 ); baseRotationPoint.add( rotationPoint ); // Create the camera. camera = new THREE.PerspectiveCamera( 45, // Angle window.innerWidth / window.innerHeight, // Aspect Ratio. 0.1, // Near view. 1000 // Far view. ); rotationPoint.add( camera ); // Build the renderer. renderer = new THREE.WebGLRenderer({ alpha: true,transparent: true }); renderer.clear() renderer.clearDepth(); element = renderer.domElement; renderer.setSize( window.innerWidth, window.innerHeight ); renderer.domElement.style.position = 'absolute'; renderer.domElement.style.top = '0px'; renderer.domElement.style.zIndex = '100'; renderer.domElement.style.margin = '0'; renderer.domElement.style.padding = '0'; /*renderer.domElement.style.clipPath = 'circle(25%)'; */ renderer.shadowMap.enabled; earthy.appendChild( element ); window.addEventListener( 'resize', onWindowResize ); // Build the controls. controls = new THREE.OrbitControls( camera, element ); controls.enablePan = true; controls.enableZoom = false; controls.maxDistance = earthRadius * 8; controls.minDistance = earthRadius * 2; controls.target.copy( new THREE.Vector3( 0, 0, -1 * earthRadius * 4 )); function setOrientationControls(e) { if (!e.alpha) { return; } controls = new THREE.DeviceOrientationControls( camera ); controls.connect(); window.removeEventListener('deviceorientation', setOrientationControls, true); } window.addEventListener('deviceorientation', setOrientationControls, true); // Ambient lights var ambient = new THREE.AmbientLight( 0x222222 ); scene.add( ambient ); // The sun. var light = new THREE.PointLight( 0xffeecc, 1, 5000 ); light.position.set( -400, 0, 100 ); scene.add( light ); // Since the sun is much bigger than a point of light, add four fillers. var light2 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light2.position.set( -400, 0, 250 ); scene.add( light2 ); var light3 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light3.position.set( -400, 0, -150 ); scene.add( light3 ); var light4 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light4.position.set( -400, 150, 100 ); scene.add( light4 ); var light5 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light5.position.set( -400, -150, 100 ); scene.add( light5 ); // Add the Earth sphere model. var geometry = new THREE.SphereGeometry( earthRadius, 128, 128 ); // Create the Earth materials. loader = new THREE.TextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var texture = loader.load( TEXTURE_PATH + 'ColorMap.jpg' ); var bump = null; bump = loader.load( TEXTURE_PATH + 'Bump.jpg' ); var spec = null; spec = loader.load( TEXTURE_PATH + 'SpecMask.jpg' ); var material = new THREE.MeshPhongMaterial({ color: "#ffffff", shininess: 5, map: texture, specularMap: spec, specular: "#666666", bumpMap: bump, }); sphere = new THREE.Mesh( geometry, material ); sphere.position.set( 0, 0, 0 ); sphere.rotation.y = Math.PI; // Focus initially on the prime meridian. sphere.rotation.y = -1 * (8.7 * Math.PI / 17); // Add the Earth to the scene.https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/Bump.jpg worldRotationPoint.add( sphere ); // Add the Earth sphere model. var geometryCloud = new THREE.SphereGeometry( earthRadius + 0.2, 128, 128 ); loader = new THREE.TextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var alpha = loader.load( TEXTURE_PATH + "alphaMap.jpg" ); var materialCloud = new THREE.MeshPhongMaterial({ alphaMap: alpha, }); materialCloud.transparent = true; sphereCloud = new THREE.Mesh( geometryCloud, materialCloud ); scene.add( sphereCloud ); // Add the skymap. window.addEventListener('resize', onWindowResize, true); } /** * Events to fire upon window resizing. */ function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } /** * Add the sun to the scene. */ function createSun() { // Add the Sun sphere model. var sunGeometry = new THREE.SphereGeometry( 100, 16, 16 ); // Create the Sun materials. var sunMaterial = new THREE.MeshLambertMaterial({ color: '#ffff55', emissive: '#ffff55', }); } /** * Updates to apply to the scene while running. */ function update() { camera.updateProjectionMatrix(); worldRotationPoint.rotation.y = degrees * Math.PI/180; sphereCloud.rotation.y += 0.00025; baseRotationPoint.rotation.y -= 0.00025; } /** * Render the scene. */ function render() { renderer.render(scene, camera); } /** * Animate the scene. */ function animate() { requestAnimationFrame(animate); update(); render(); } function addSkybox() { var urlPrefix = TEXTURE_PATH; var urls = [ urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', ]; var loader = new THREE.CubeTextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var textureCube = loader.load( urls ); textureCube.format = THREE.RGBFormat; var shader = THREE.ShaderLib[ "cube" ]; shader.uniforms[ "tCube" ].value = textureCube; var material = new THREE.ShaderMaterial( { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: shader.uniforms, depthWrite: false, side: THREE.BackSide } ); } in background inside Threejs object([https://codepen.io/bartuc/pen/yMMyav][2]) const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/'; /** * Create the animation request. */ if (!window.requestAnimationFrame) { window.requestAnimationFrame = (function() { return window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || window.webkitRequestAnimationFrame || function (callback, element) { // 60 FPS window.setTimeout(callback, 1000 / 60); }; })(); } /** * Set our global variables. */ var camera, scene, renderer, effect, controls, element, earthy, sphere, sphereCloud, rotationPoint; var degreeOffset = 90; var earthRadius = 80; var getEarthRotation = function() { // Get the current time. var d = new Date(); var h = d.getUTCHours(); var m = d.getUTCMinutes(); // Calculate total minutes. var minutes = h * 60; minutes += m; // Turn minutes into degrees. degrees = minutes/3.9907; // Add an offset to match UTC time. degrees += degreeOffset; return degrees; } var degrees = getEarthRotation(); // Calculate Earth's rotation position. setInterval(function() { // Get the current time. var d = new Date(); var h = d.getUTCHours(); var m = d.getUTCMinutes(); // Calculate total minutes. var minutes = h * 60; minutes += m; // Turn minutes into degrees. degrees = minutes/3.9907; // Add an offset to match UTC time. degrees += degreeOffset; }, 60000); init(); animate(); var string = ''; /** * Initializer function. */ function init() { // Build the earthy = document.createElement( 'div' ); document.body.appendChild( earthy ); // Create the scene. scene = new THREE.Scene(); // Create a rotation point. baseRotationPoint = new THREE.Object3D(); baseRotationPoint.position.set( 0, 0, 0 ); scene.add( baseRotationPoint ); // Create world rotation point. worldRotationPoint = new THREE.Object3D(); worldRotationPoint.position.set( 0, 0, 0 ); scene.add( worldRotationPoint ); rotationPoint = new THREE.Object3D(); rotationPoint.position.set( 0, 0, earthRadius * 4 ); baseRotationPoint.add( rotationPoint ); // Create the camera. camera = new THREE.PerspectiveCamera( 45, // Angle window.innerWidth / window.innerHeight, // Aspect Ratio. 0.1, // Near view. 1000 // Far view. ); rotationPoint.add( camera ); // Build the renderer. renderer = new THREE.WebGLRenderer({ alpha: true,transparent: true }); renderer.clear() renderer.clearDepth(); element = renderer.domElement; renderer.setSize( window.innerWidth, window.innerHeight ); renderer.domElement.style.position = 'absolute'; renderer.domElement.style.top = '0px'; renderer.domElement.style.zIndex = '100'; renderer.domElement.style.margin = '0'; renderer.domElement.style.padding = '0'; /*renderer.domElement.style.clipPath = 'circle(25%)'; */ renderer.shadowMap.enabled; earthy.appendChild( element ); window.addEventListener( 'resize', onWindowResize ); // Build the controls. controls = new THREE.OrbitControls( camera, element ); controls.enablePan = true; controls.enableZoom = false; controls.maxDistance = earthRadius * 8; controls.minDistance = earthRadius * 2; controls.target.copy( new THREE.Vector3( 0, 0, -1 * earthRadius * 4 )); function setOrientationControls(e) { if (!e.alpha) { return; } controls = new THREE.DeviceOrientationControls( camera ); controls.connect(); window.removeEventListener('deviceorientation', setOrientationControls, true); } window.addEventListener('deviceorientation', setOrientationControls, true); // Ambient lights var ambient = new THREE.AmbientLight( 0x222222 ); scene.add( ambient ); // The sun. var light = new THREE.PointLight( 0xffeecc, 1, 5000 ); light.position.set( -400, 0, 100 ); scene.add( light ); // Since the sun is much bigger than a point of light, add four fillers. var light2 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light2.position.set( -400, 0, 250 ); scene.add( light2 ); var light3 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light3.position.set( -400, 0, -150 ); scene.add( light3 ); var light4 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light4.position.set( -400, 150, 100 ); scene.add( light4 ); var light5 = new THREE.PointLight( 0xffffff, 0.6, 4000 ); light5.position.set( -400, -150, 100 ); scene.add( light5 ); // Add the Earth sphere model. var geometry = new THREE.SphereGeometry( earthRadius, 128, 128 ); // Create the Earth materials. loader = new THREE.TextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var texture = loader.load( TEXTURE_PATH + 'ColorMap.jpg' ); var bump = null; bump = loader.load( TEXTURE_PATH + 'Bump.jpg' ); var spec = null; spec = loader.load( TEXTURE_PATH + 'SpecMask.jpg' ); var material = new THREE.MeshPhongMaterial({ color: "#ffffff", shininess: 5, map: texture, specularMap: spec, specular: "#666666", bumpMap: bump, }); sphere = new THREE.Mesh( geometry, material ); sphere.position.set( 0, 0, 0 ); sphere.rotation.y = Math.PI; // Focus initially on the prime meridian. sphere.rotation.y = -1 * (8.7 * Math.PI / 17); // Add the Earth to the scene.https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/Bump.jpg worldRotationPoint.add( sphere ); // Add the Earth sphere model. var geometryCloud = new THREE.SphereGeometry( earthRadius + 0.2, 128, 128 ); loader = new THREE.TextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var alpha = loader.load( TEXTURE_PATH + "alphaMap.jpg" ); var materialCloud = new THREE.MeshPhongMaterial({ alphaMap: alpha, }); materialCloud.transparent = true; sphereCloud = new THREE.Mesh( geometryCloud, materialCloud ); scene.add( sphereCloud ); // Add the skymap. window.addEventListener('resize', onWindowResize, true); } /** * Events to fire upon window resizing. */ function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } /** * Add the sun to the scene. */ function createSun() { // Add the Sun sphere model. var sunGeometry = new THREE.SphereGeometry( 100, 16, 16 ); // Create the Sun materials. var sunMaterial = new THREE.MeshLambertMaterial({ color: '#ffff55', emissive: '#ffff55', }); } /** * Updates to apply to the scene while running. */ function update() { camera.updateProjectionMatrix(); worldRotationPoint.rotation.y = degrees * Math.PI/180; sphereCloud.rotation.y += 0.00025; baseRotationPoint.rotation.y -= 0.00025; } /** * Render the scene. */ function render() { renderer.render(scene, camera); } /** * Animate the scene. */ function animate() { requestAnimationFrame(animate); update(); render(); } function addSkybox() { var urlPrefix = TEXTURE_PATH; var urls = [ urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', urlPrefix + 'test.jpg', ]; var loader = new THREE.CubeTextureLoader(); loader.setCrossOrigin( 'https://s.codepen.io' ); var textureCube = loader.load( urls ); textureCube.format = THREE.RGBFormat; var shader = THREE.ShaderLib[ "cube" ]; shader.uniforms[ "tCube" ].value = textureCube; var material = new THREE.ShaderMaterial( { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: shader.uniforms, depthWrite: false, side: THREE.BackSide } ); } like this: https://codepen.io/danacrypto/pen/yLKoLXY I made it but it has some problems. I like use this inside my site made with WordPress and elementor. I'm Not perfect # javascript [1]: https://codepen.io/soju22/pen/JjEqebK [2]: https://codepen.io/bartuc/pen/yMMyav
How to add texture to BufferGeometry faces.?
I have created a bufferGeometry , which consist of 5 planes (100x25) with two triangles each. function createGeometry() { var geometry = new THREE.PlaneGeometry(100, 25, 1); return geometry; } function createScene() { var bufferGeometry = new THREE.BufferGeometry(); var radius = 125; var count = 5; var positions = []; var normals = []; var colors = []; var vector = new THREE.Vector3(); var color = new THREE.Color( 0xffffff ); var heartGeometry = createGeometry(); var geometry = new THREE.Geometry(); var step = 0; for ( var i = 1, l = count; i <= l; i ++ ) { geometry.copy( heartGeometry ); const y = i * 30 geometry.translate(-100, y, 0); // color.setHSL( ( i / l ), 1.0, 0.7 ); geometry.faces.forEach( function ( face ) { positions.push( geometry.vertices[ face.a ].x ); positions.push( geometry.vertices[ face.a ].y ); positions.push( geometry.vertices[ face.a ].z ); positions.push( geometry.vertices[ face.b ].x ); positions.push( geometry.vertices[ face.b ].y ); positions.push( geometry.vertices[ face.b ].z ); positions.push( geometry.vertices[ face.c ].x ); positions.push( geometry.vertices[ face.c ].y ); positions.push( geometry.vertices[ face.c ].z ); normals.push( face.normal.x ); normals.push( face.normal.y ); normals.push( face.normal.z ); normals.push( face.normal.x ); normals.push( face.normal.y ); normals.push( face.normal.z ); normals.push( face.normal.x ); normals.push( face.normal.y ); normals.push( face.normal.z ); colors.push( color.r ); colors.push( color.g ); colors.push( color.b ); colors.push( color.r ); colors.push( color.g ); colors.push( color.b ); colors.push( color.r ); colors.push( color.g ); colors.push( color.b ); }); } bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.FrontSide }); var mesh = new THREE.Mesh( bufferGeometry, material ); scene.add( mesh ); } Now instead of coloring each plane how can i add a text to each plane. Say i just want to display 1,2,3,4,5 at the center of each plane. What I know is the following has to be done to add the texture. Generate texture from canvas Change the material to Shader Material with map:texture Add uvs to bufferGeometry. But what is the relation between uvs and texture. I have the texture creating function //not sure for each character or one texture as a single texture function createTexture(ch){ var fontSize = 20; var c = document.createElement('canvas'); c.width = 100; c.height = 25; var ctx = c.getContext('2d'); ctx.font = fontSize+'px Monospace'; ctx.fillText(ch, c.width/2, c.height/2); var texture = new THREE.Texture(c); texture.flipY = false; texture.needsUpdate = true; return texture; } Full DEMO Code EDIT I am considering performance as high priority for this experiment. We can add each mesh for each text, but that will increase the number of mesh in screen and reduce performance. I am looking for any idea with a single mesh as in my example. The closest I found is this, but i didn't understood the exact technique they are using.
You've to copy the first uv channel of the .faceVertexUvs property form the THREE.Geometry, similar as you do it with the vertex coordinates and normal vectors: for ( var i = 1, l = count; i <= l; i ++ ) { geometry.copy( heartGeometry ); const y = i * 30 geometry.translate(-100, y, 0); geometry.faces.forEach( function ( face ) { let f = [face.a, face.b, face.c]; for (let i=0; i < 3; ++i) { positions.push( ...geometry.vertices[f[i]].toArray() ); normals.push( ...face.normal.toArray() ); colors.push( ...color.toArray() ); } } ); geometry.faceVertexUvs[0].forEach( function ( faceUvs ) { for (let i=0; i < 3; ++i) { uv.push( ...faceUvs[i].toArray() ); } } ); } If you want to define multiple textures for one geometry, then you've to use multiple THREE.Materials for one THREE.Mesh. Define groups (see .addGroup) for the THREE.BufferGeometry. Each group associates a range of vertices to a material. var bufferGeometry = new THREE.BufferGeometry(); bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); bufferGeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv, 2 ) ); let materials = [] let v_per_group= positions.length / 3 / count; for ( var i = 0; i < count; i ++ ) { bufferGeometry.addGroup(i * v_per_group, v_per_group, i); let material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.FrontSide, map : createTexture("button" + (i+1)) }); materials.push(material); } var mesh = new THREE.Mesh( bufferGeometry, materials ); scene.add( mesh ); var camera, scene, renderer, controls, stats; init(); animate(); function init() { renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 45.0, window.innerWidth / window.innerHeight, 100, 1500.0 ); camera.position.z = 480.0; scene.add( camera ); controls = new THREE.TrackballControls( camera, renderer.domElement ); controls.minDistance = 100.0; controls.maxDistance = 800.0; controls.dynamicDampingFactor = 0.1; scene.add( new THREE.AmbientLight( 0xffffff, 1 ) ); createScene(); //stats = new Stats(); //document.body.appendChild( stats.dom ); window.addEventListener( 'resize', onWindowResize, false ); } function createGeometry() { var geometry = new THREE.PlaneGeometry(100, 25, 1); return geometry; } function createTexture(ch){ var fontSize = 20; var c = document.createElement('canvas'); c.width = 128; c.height = 32; var ctx = c.getContext('2d'); ctx.beginPath(); ctx.rect(0, 0, 128, 32); ctx.fillStyle = "white"; ctx.fill(); ctx.fillStyle = "black"; ctx.font = fontSize+'px Monospace'; ctx.fillText(ch, 20, 24); var texture = new THREE.Texture(c); texture.flipY = true; texture.needsUpdate = true; return texture; } function createScene() { var radius = 125; var count = 5; var vector = new THREE.Vector3(); var color = new THREE.Color( 0xffffff ); var heartGeometry = createGeometry(); var geometry = new THREE.Geometry(); var positions = []; var normals = []; var colors = []; var uv = []; for ( var i = 1, l = count; i <= l; i ++ ) { geometry.copy( heartGeometry ); const y = i * 30 geometry.translate(-100, y, 0); geometry.faces.forEach( function ( face ) { let f = [face.a, face.b, face.c]; for (let i=0; i < 3; ++i) { positions.push( ...geometry.vertices[f[i]].toArray() ); normals.push( ...face.normal.toArray() ); colors.push( ...color.toArray() ); } } ); geometry.faceVertexUvs[0].forEach( function ( faceUvs ) { for (let i=0; i < 3; ++i) { uv.push( ...faceUvs[i].toArray() ); } } ); } var bufferGeometry = new THREE.BufferGeometry(); bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); bufferGeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv, 2 ) ); let materials = [] let v_per_group = positions.length / 3 / count; for ( var i = 0; i < count; i ++ ) { bufferGeometry.addGroup(i * v_per_group, v_per_group, i); let material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, side: THREE.FrontSide, map : createTexture("button" + (i+1)) }); materials.push(material); } var mesh = new THREE.Mesh( bufferGeometry, materials ); scene.add( mesh ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { requestAnimationFrame( animate ); controls.update(); //stats.update(); renderer.render( scene, camera ); } <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script> <script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
How to reflect an object in itself?
Is it possible that an object reflects in itself? I like to receive a self reflection on a metallic object. So basicially, the two rings of the mechanism should be reflected in the lower part. 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 = 1; controls.maxDistance = 8; controls.noPan = false; 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 feinleinentexture = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' ); feinleinentexture.anisotropy = 16; feinleinentexture.wrapS = feinleinentexture.wrapT = THREE.RepeatWrapping; feinleinentexture.repeat.set( 5, 5 ); var feinleinen = new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinentexture } ); // Chrome var path = "textures/chrome/"; var format = '.jpg'; 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 ); var chrome = new THREE.MeshPhongMaterial( { color : 0x151515, specular : 0xffffff, shininess : 200, envMap : envMap, combine : THREE.MixOperation, // or THREE.AddOperation, THREE.MultiplyOperation reflectivity : 0.8 } ); // basis var basisGeometry = new THREE.BoxGeometry(1.8,0.012,3); var basis = new THREE.Mesh(basisGeometry, feinleinen); basis.castShadow = false; basis.receiveShadow = true; basis.position.set( 0, -0.47, 0 ); scene.add(basis); // 2 Ring var loader = new THREE.JSONLoader(); loader.load('/models/2ring.js', function(geo, mat){ var mesh = new THREE.Mesh(geo, chrome); mesh.position.set( 0.08, - 0.477, -0.2 ); mesh.rotation.set( 0, - Math.PI / 0.67, 0 ); mesh.scale.set( 0.1, 0.1, 0.1 ); 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 want an object to reflect itself when using a three.js renderer. Environment mapping, which you have implemented, is based on an approximation that the environment being reflected is (infinitely) far away. Even if you used a CubeCamera for your environment map, as in this example, you would have the same problem. The solution using three.js is to use a form of raytracing. three.js has a RaytracingRenderer, and a simple demo, but that renderer is currently not highly-supported, nor does it run at real-time frame rates. three.js r.71
Rotate the mergeometry object at its center in Three.js
I am struggling to find the way to rotate the object at its center. At the moment i am able to rotate the scene, but when i do the rotation, the object goes away from the user. I look into the some the already asked questions in the same line on the forum, but couldn't able to get it work. Below is the part of the html/three.js file i am using /attached you will find the complete working example.Any help is greatly appreciated <script src="../build/three.min.js"></script> <script src="js/controls/TrackballControls.js"></script> <script src="js/libs/stats.min.js"></script> <script> var container, stats; var camera, controls, scene, renderer; var pickingData = [], pickingTexture, pickingScene; var objects = []; var highlightBox; var splitCoord; var avStdProp; var mouse = new THREE.Vector2(); var offset = new THREE.Vector3( 10, 10, 10 ); var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 ); geom.colorsNeedUpdate = true; init(); animate(); function init() { container = document.getElementById( "container" ); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 ); camera.position.x=250; camera.position.y=300; camera.position.z=400; renderer = new THREE.WebGLRenderer( { antialias: true } ); controls = new THREE.TrackballControls(camera); controls.rotateSpeed = 1.0; controls.zoomSpeed = 4; controls.panSpeed = 0.8; controls.noZoom = false; controls.noPan = false; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; scene = new THREE.Scene(); pickingScene = new THREE.Scene(); pickingTexture = new THREE.WebGLRenderTarget(800, 800); pickingTexture.minFilter = THREE.LinearFilter; pickingTexture.generateMipmaps = false; scene.add( new THREE.AmbientLight( 0x555555 ) ); var light = new THREE.SpotLight( 0xffffff, 1.5 ); light.position.set( 0, 500, 2000 ); scene.add( light ); var geometry = new THREE.Geometry(), pickingGeometry = new THREE.Geometry(), pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ), defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } ); function applyVertexColors( g, c ) { g.faces.forEach( function( f ) { var n = ( f instanceof THREE.Face3 ) ? 3 : 4; for( var j = 0; j < n; j ++ ) { f.vertexColors[ j ] = c; } } ); } var color = new THREE.Color(); var matrix = new THREE.Matrix4(); var quaternion = new THREE.Quaternion(); var coord="219_163_189;130_173_179;161_113_231;92_103_176;169_193_180;161_165_187;262_163_166;198_143_155;161_189_155;125_121_107"; splitCoord=coord.split(";"); var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;0_255_0;0_0_255;0_255_255;255_255_0;210_210_45"; var splitCoordColor=coordColr.split(";"); var avgStd="1_0;3_0;0_0;2_0;3_0;2_0;0_0;1_0;3_0;3_0.35"; avStdProp=avgStd.split(";"); for ( var i = 0; i < splitCoord.length; i++ ) { var position = new THREE.Vector3(); var xyz=splitCoord[i].split("_"); var col=splitCoordColor[i].split("_"); position.x = xyz[0]; position.y = xyz[1]; position.z = xyz[2]; var rotation = new THREE.Euler(); rotation.x = 0 rotation.y = 0; rotation.z = 0; var scale = new THREE.Vector3(); scale.x = 200 + 100; scale.y = 200 + 100; scale.z = 200 + 100; quaternion.setFromEuler( rotation, false ); matrix.compose( position, quaternion, scale ); // give the geom's vertices a random color, to be displayed col[0]=col[0]/255; col[1]=col[1]/255; col[2]=col[2]/255; applyVertexColors(geom, color.setRGB(col[0], col[1], col[2])); geometry.merge( geom, matrix ); // give the geom's vertices a color corresponding to the "id" applyVertexColors( geom, color.setHex( i ) ); pickingGeometry.merge( geom, matrix ); pickingData[ i ] = { position: position, rotation: rotation, scale: scale }; } var drawnObject = new THREE.Mesh( geometry, defaultMaterial ); scene.add( drawnObject ); pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) ); highlightBox = new THREE.Mesh( new THREE.BoxGeometry( 0.009, 0.009, 0.009 ), new THREE.MeshLambertMaterial( { color: 0xffffff } ) ); scene.add( highlightBox ); //renderer.setClearColor( 0xffffff ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize(800,800); renderer.sortObjects = false; container.appendChild( renderer.domElement ); renderer.domElement.addEventListener( 'mousemove', onMouseMove ); } // function onMouseMove( e ) { mouse.x = e.clientX; mouse.y = e.clientY; } function pick() { //render the picking scene off-screen renderer.render( pickingScene, camera, pickingTexture ); //create buffer for reading single pixel var pixelBuffer = new Uint8Array( 4 ); //read the pixel under the mouse from the texture renderer.readRenderTargetPixels(pickingTexture, mouse.x+window.pageXOffset, pickingTexture.height - (mouse.y+window.pageYOffset), 1, 1, pixelBuffer); //interpret the pixel as an ID var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2]); var data = pickingData[ id ]; if (data) { //move our highlightBox so that it surrounds the picked object if (data.position && data.rotation && data.scale && controls.enabled){ highlightBox.position.copy( data.position ); highlightBox.rotation.copy( data.rotation ); highlightBox.scale.copy( data.scale ).add( offset ); highlightBox.visible = true; } } else { highlightBox.visible = false; } } function animate() { requestAnimationFrame( animate ); render(); //stats.update(); } function render() { controls.update(); pick(); renderer.render(scene, camera); } any help?
You can set your objects geometry to center, so the center of the mesh will then be at position (0,0,0) and it wont "move away" while rotating. Do it like this: geometry.center(); var drawnObject = new THREE.Mesh( geometry, defaultMaterial ); scene.add( drawnObject ); Update Because you want to use picking in an unusual way by saving your geometrys coordinates into an array, centering the geometry doesnt help you. Your question was "Rotate the mergeometry object at its center", but it seems like you want to rotate the camera around your geometrys center. Calculate the bounding sphere of your geometry and set the controls target to its position: drawnObject.geometry.computeBoundingSphere(); controls.target = drawnObject.geometry.boundingSphere.center;
Three.js, no shadow rendered (.stl files)
I'm using three.js and I'm trying to make a good viewer for .stl files. But I have a big problem with the shadow, for some files it's ok and for some other it's just horrible. (Most of the time, it's stl file that come from Blender that don't work). Here are the two different render with a "normal" file and the same file import/export with Blender. Images : http://imageup.fr/uploads/1367501292.jpeg & http://imageup.fr/uploads/1367501311.jpeg Here is the code: <script src="scripts/three.min.js"></script> <script src="three/js/loaders/STLLoader.js"></script> <script src="three/js/Detector.js"></script> <script src="three/js/controls/TrackballControls.js"></script> <div id='3d' style='width:400px;height:300px;margin:auto;position:relative;border:5px solid white;border-radius:5px;'> <script> var modele = document.getElementById('modele3d').value; if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); var container, stats; var camera, cameraTarget, scene, renderer; init(); animate(); function init() { container = document.getElementById('3d'); camera = new THREE.PerspectiveCamera( 45, 400 / 300, 0.1, 10000 ); camera.position.set( 200, 200, 200 ); cameraTarget = new THREE.Vector3( 0, 0, 0 ); scene = new THREE.Scene(); scene.fog = new THREE.Fog( 0x1875cd, 0, 100000 ); var material = new THREE.MeshPhongMaterial( { ambient: 0xaeadad, color: 0xfefcfc, specular: 0x111111, shininess: 200} ); var loader = new THREE.STLLoader(); loader.addEventListener( 'load', function ( event ) { var geometry = event.content; var mesh = new THREE.Mesh( geometry, material ); mesh.position.set( 0, 0, 0 ); mesh.rotation.set( - Math.PI / 2, 0, 0 ); // Recherche et envoi des tailles // geometry.computeBoundingBox(); var largeur = (mesh.geometry.boundingBox.max.x)-(mesh.geometry.boundingBox.min.x); var hauteur = (mesh.geometry.boundingBox.max.y)-(mesh.geometry.boundingBox.min.y); var profondeur = (mesh.geometry.boundingBox.max.z)-(mesh.geometry.boundingBox.min.z); var tailles = largeur + " " + hauteur + " " + profondeur; var prix = document.getElementById('prototype_prix').value; if(prix==0){ document.getElementById('prototype_taille1').value = Math.round(largeur); document.getElementById('prototype_taille2').value = Math.round(hauteur); document.getElementById('prototype_taille3').value = Math.round(profondeur); document.getElementById('prototype_taille1_base').value = largeur; document.getElementById('prototype_taille2_base').value = hauteur; document.getElementById('prototype_taille3_base').value = profondeur; } geometry.computeBoundingSphere(); var radius = mesh.geometry.boundingSphere.radius; mesh.position.set( 0, -radius/2, 0 ); var d = 300/(2*radius); mesh.scale.set( d, d, d ); mesh.castShadow = true; mesh.receiveShadow = true; scene.add( mesh ); } ); loader.load( 'images/'+modele); // Lights scene.add( new THREE.AmbientLight( 0x777777 ) ); addShadowedLight( 1, 1, 1, 0xffffff, 0.8 ); addShadowedLight( 0.5, 1, -1, 0xfcd891, 0.6 ); // renderer renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } ); renderer.setSize( 400, 300); renderer.setClearColor( scene.fog.color, 1 ); renderer.gammaInput = true; renderer.gammaOutput = true; renderer.physicallyBasedShading = true; renderer.shadowMapEnabled = true; renderer.shadowMapCullFace = THREE.CullFaceBack; container.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); // Trackball enhanced_control = new THREE.TrackballControls(camera,renderer.domElement); } 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; directionalLight.shadowCameraNear = 0; directionalLight.shadowCameraFar = 20; directionalLight.shadowMapWidth = 1024; directionalLight.shadowMapHeight = 1024; directionalLight.shadowBias = -0.005; directionalLight.shadowDarkness = 0.15; } function onWindowResize() { camera.aspect = 400 / 300; renderer.setSize( 400, 300); } function animate() { requestAnimationFrame( animate ); enhanced_control.update(); render(); } function render() { var timer = Date.now() * 0.0005; camera.lookAt( cameraTarget ); renderer.render( scene, camera ); } </script> <p style='position:relative;margin-top:-310px;margin-left:3px;float:left;color:white;text-shadow:1px 1px 1px #135da4'>Rendu 3D :</p> </div> I hope you can help me, I have already passed a lot of time trying to make the render works :s