I have a lot of meshes in my code and I want that the renderer renders the object that should be infront, something like this -->https://i-msdn.sec.s-msft.com/dynimg/IC72309.gif I already read about the render Depth but I don't know how to use it in the code. Lets say I have two spheres:
var shape1 = new THREE.SphereGeometry(50,10,8,10)
var cover1 = new THREE.MeshNormalMaterial();
var Sphere1 = new THREE.Mesh(shape1, cover1);
scene.add(Sphere1);
Sphere1.position.set(10,0,0);
var shape2 = new THREE.SphereGeometry(50,10,8,10)
var cover2 = new THREE.MeshNormalMaterial();
var Sphere2 = new THREE.Mesh(shape2, cover2);
scene.add(Sphere2);
Sphere2.position.set(-10,0,0);
Now I want that the first Sphere overlapps the other one without changing the z-axes.
The site that I'm using is http://gamingjs.com/ice/ and it should be the version r52.
You can disable depthWrite of the material, so the object will be rendered on top of everything else.
var cover1 = new THREE.MeshNormalMaterial({ depthWrite: false, depthTest: false });
Related
I have a bug where I copy the Quaternion of one object and pass it to a function where it gets applied to another object to keep their rotations in sync. I cannot get the Quaternion to apply to the second object.
Given object 1 is msh and object 2 is msh2, this code will not apply the rotation of msh to msh2
var rot = new THREE.Quaternion().copy(msh.rotation);
msh2.rotation.copy(rot);
You can see this further in this Stack Snippet which contains the problem in the smallest reproducable fashion (but isn't the exact code I'm working with in my real project)
var renderer = new THREE.WebGLRenderer({canvas : $("#can")[0]});
renderer.setSize($("#can").width(), $("#can").height());
var cam = new THREE.PerspectiveCamera(45, $("#can").width() / $("#can").height(), 0.1, 100);
cam.position.set(0,2,6);
cam.quaternion.multiply(new THREE.Quaternion().setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), -Math.PI/8 ));
var scene = new THREE.Scene();
var geo = new THREE.BoxGeometry(1,1,1);
var mat = new THREE.MeshBasicMaterial({color : 0xff0000});
var msh = new THREE.Mesh(geo,mat);
scene.add(msh);
geo = new THREE.BoxGeometry(1,2,1);
mat = new THREE.MeshBasicMaterial({color : 0xff00ff});
var msh2 = new THREE.Mesh(geo,mat);
msh2.position.set(2,0,0);
scene.add(msh2);
function render() {
requestAnimationFrame( render );
msh.rotateX(0.001);
msh.rotateY(0.002);
//For some reason, this doesn't work??
var rot = new THREE.Quaternion().copy(msh.rotation);
msh2.rotation.copy(rot);
//Yet this does (but it doesn't fit the flow of my
//original project because I don't want to pass
//objects around.
//msh2.rotation.copy(msh.rotation);
renderer.render( scene, cam );
}
render();
<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="can" width="400" height="300"></canvas>
Also see the JSFiddle here
Am I missing something here? I do this with Vector3 all the time so I don't see why I can't do it here...
msh.rotation is an instance of THREE.Euler, but you're trying to copy to/from THREE.Quaternion. msh2.rotation.copy(msh.rotation) should work fine, as would msh2.quaternion.copy(msh.quaternion)
If I understand you correctly you want both objects to rotate at the same speed and angle. You just need to update the render(); function with these two lines:
msh2.rotateX(0.001);
msh2.rotateY(0.002);
Updated JSFiddle
what works:
I am using threejs revision 73.
I want to render a tool with the WebGLRenderer.
The tool consists of 3 Meshes. Each mesh consists of a BufferGeometry and a MeshLambertMaterial:
var geometry = new THREE.BufferGeometry();
var material = new THREE.MeshLambertMaterial();
var mesh = new THREE.Mesh(geometry, material);
The result looks like the following:
what I want to archive:
Now I want to make the tool look more realistic by applying a Texture ("img/tablereflection.bmp", grayscale 256x256px, bmp). I am unsure what is the best approach if I want this texture to affect my reflectivity behavior.
What I do, is:
var geometry = new THREE.BufferGeometry();
var material = new THREE.MeshLambertMaterial({
map: new THREE.TextureLoader().load("img/tablereflection.bmp")
});
var mesh = new THREE.Mesh(geometry, material);
But the result looks like that:
That is not what I want to have. It should look like:
Can someone tell me please, what I might be missing?
Edits
My light function is
function initLight(scene, camera) {
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
var leftLight = new THREE.PointLight(0x888888, 0.7, 0);
leftLight.position.set(-2, 5, 2);
camera.add(leftLight);
var rightLight = new THREE.PointLight(0x888888, 0.7, 0);
rightLight.position.set(2, 5, 2);
camera.add(rightLight);
}
I've already tried to use The material browser for MeshLambertMaterial and possibly was able to archieve what I wanted as you can see here using these settings , but as you can see the Type is now empty and so I am not sure what happens behind the scene. Where is the error? Im glad for any hints.
I am trying to render image texture dynamically but in console it displays Uncaught TypeError: Cannot read property 'width' of undefined. few suggest to make needsUpdate = true to false. When I am doing so some unpleasing black patch is appearing .But I need it true. how can i do so?
Actual code is very big i am pointing where problem occurs..
var g = new THREE.PlaneGeometry(100,100);
var tx =THREE.ImageUtils.loadTexture(imgUrl,undefined,callback,callbackError);
var m = new THREE.MeshBasicMaterial({
map:tx
});
m.map.needsUpdate = true; //1
tx.needsUpdate = true; //2
////if 1 and 2 is commented then its ok but rendering is not good
var b = THREE.SceneUtils.createMultiMaterialObject(g,[
m
,new THREE.MeshBasicMaterial({wireframeLinewidth:3,color:0x222222,wireframe:true})
]);
There may be a situation when renderer tries to use you texture before it is loaded. When you do
var tx =THREE.ImageUtils.loadTexture(imgUrl,undefined,callback,callbackError);
the texture is returned but image itself is not yet loaded. So renderer tries to take width and height to find out is your texture power of 2 and throws an error in this moment.
You may try to wrap creation of your object and placing it to the scene into the callback function and pass it as the third parameter to the loadTexture method. Something like that:
var geometry = new THREE.PlaneGeometry(100, 100);
var tx =THREE.ImageUtils.loadTexture(imgUrl, undefined, function(texture){
var material = new THREE.MeshBasicMaterial({
map: texture
});
var b = THREE.SceneUtils.createMultiMaterialObject(
geometry,
[
material,
new THREE.MeshBasicMaterial({wireframeLinewidth:3,color:0x222222,wireframe:true})
]
);
}, callbackError);
I'm experimenting with Bjørn Sandvik's really great process for importing terrain data into a scene.
Check it out:
http://blog.thematicmapping.org/2013/10/terrain-building-with-threejs.html
var terrainLoader = new THREE.TerrainLoader();
terrainLoader.load('../assets/jotunheimen.bin', function(data) {
var geometry = new THREE.PlaneGeometry(60, 60, 199, 199);
for (var i = 0, l = geometry.vertices.length; i < l; i++) {
geometry.vertices[i].z = data[i] / 65535 * 10;
}
var material = new THREE.MeshPhongMaterial({
color: 0xdddddd,
wireframe: true
});
var plane = new THREE.Mesh(geometry, material);
scene.add(plane);
});
My intent is to use this to display elevation data from a time series, so multiple .bin files will be loaded to provide data representing a period of several years to show change over time.
I am having difficulties updating the geometry with new data. I think that my difficulties stem from the plane and geometry variables being defined inside of a function, meaning that they are undefined in the global context. So later when I call those variables they don't have any value associated with them.
Does anyone have an idea of how I can update this geometry with new data loaded using the TerrainLoader?
anything you .add() to the scene object is visible as an element of the scene.children array -- to you can still reference your plane and the geometry of it as plane.geometry -- the the plane is the only object in the scene, it will probably be scene.children[0].geometry
See this page: https://github.com/mrdoob/three.js/wiki/Updates for hints on how to let THREE know the geometry is changing
In three.js, I want to add a mesh to a position in the scene
I've tried:
// mesh is an instance of THREE.Mesh
// scene is an instance of THREE.Scene
scene.add(mesh)
scene.updateMatrixWorld(true)
mesh.matrixWorld.setPosition(new THREE.Vector3(100, 100, 100))
scene.updateMatrix()
BUT it didn't affect anything.
What should I do ?
I would recommend you to check the documentation over here:
http://threejs.org/docs/#Reference/Objects/Mesh
As you can see on the top of the docu-page, Mesh inherits from "Object3D". That means that you can use all methods or properties that are provided by Object3D. So click on the "Object3D" link on the docu-page and check the properties list. You will find the property ".position". Click on ".position" to see what data-type it is. Paha..its Vector3.
So try to do the following:
// scene is an instance of THREE.Scene
scene.add(mesh);
mesh.position.set(100, 100, 100);
i saw it on a github earlier. (three.js r71 )
mesh.position.set(100, 100, 100);
and can be done for individuals
mesh.position.setX(200);
mesh.position.setZ(200);
reference: https://threejs.org/docs/#api/math/Vector3
detailed explanation is below:
since mesh.position is "Vector3". Vector3() has setX() setY() and setZ() methods. we can use it like this.
mesh.position = new THREE.Vector3() ; //see position is Vector3()
vector1 = new THREE.Vector3();
mesh.position.setX(100); //or this
vector1.setX(100) // because all of them is Vector3()
camera1.position.setZ(100); // or this
light1.position.setY(100) // applicable to any object.position
I prefer to use Vector3 to set position.
let group = new THREE.Group();
// position of box
let vector = new THREE.Vector3(10, 10, 10);
// add wooden Box
let woodenBox = new THREE.Mesh(boxGeometry, woodMaterial);
//update postion
woodenBox.position.copy(vector);
// add to scene
group.add(woodenBox)
this.scene.add(group);
If some one looking for way to update position from Vector3
const V3 = new THREE.Vector3(0,0,0) // Create variable in zero position
const box = new THREE.Mesh(geometry, material) // Create an object
Object.assign(box.position, V3) // Put the object in zero position
OR
const V3 = new THREE.Vector3(0,0,0) // Create variable in zero position
const box = new THREE.Mesh(geometry, material) // Create an object
box.position.copy(V3)