What would be the best way to create a continuous-in-every-direction floor in my canvas three.js scene?
Would it be better to attach a THREE.PlaneGeometry to the camera position, so that it travels with the camera.
Or is there another way of texturing the floor of the scene with a texture.
I'm having some trouble with the visibility of my PlaneGeometry, for some reason I have to be a certain distance from it to see it.
/* Floor */
var geometry = new THREE.PlaneGeometry( 1000, 1000, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
var floor = new THREE.Mesh( geometry, material );
floor.material.side = THREE.DoubleSide;
floor.rotation.x = de2ra(90);
scene.add( floor );
Open to all techniques!
I have an infinite ocean floor in my top-down game. I reposition it to the camera's xy-coordinates (keeping a distance with z). I then modify the texture's offset property so that it appears the floor is moving even though it's glued to the camera.
Regarding "trouble with the visibility of my PlaneGeometry", you probably hit the camera's near or far projection planes (distances) - anything closer than near or further than far is clipped, i.e. culled, i.e. invisible. You can configure it in the camera's constructor.
Related
We want to create a 3d shoe designing tool, where you can design patterns and upload them to the shoe.
I am trying to place an image on a Threejs material. I am able to update the map, but the texture is blurry. I am new to Threejs, so I do not have concepts clear. I don't understand if aspect ratio is the issue or something else.
This how I am loading texture:
var texture_loader = new THREE.TextureLoader();
var texture = texture_loader.load( 'https://ik.imagekit.io/toesmith/pexels-photo-414612_D4wydSedY.jpg', function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.offset.set( 0, 0 );
texture.repeat.set( 1, 1 );
vamp.material = new THREE.MeshPhongMaterial({
map: texture,
color: new THREE.Color('#f2f2f2'),
shininess: 20,
});
});
This is what I am getting
But the expected behavior should be
If anyone could help, that would be great. Thanks
Here is the link to the Codepen code
The problem is that your UVs are occupying a very small area in texture coordinates. As they are now, it looks like your UVs are taking up this much room (see red area):
And that's why it gives the impression that your texture is blurry. What you need to do is make your UVs take up more space, like this:
There are 2 ways to achieve this.
Scale UVs up: Import your model into Blender, and change the UV mapping of the mesh to occupy more of the [0, 1] range.
Scale texture down: You could get creative with the texture.repeat property and use it to scale down your texture to match your existing UVs. Then you'd need to offset it so it's centered correctly. Something like:
texture.repeat = new THREE.Vector2(10, 10);
texture.offset = new THREE.Vector2(xx, yy);
I am trying to create a gizmo (a 3D cube) that shows rotation of camera in 3D space. I am using three.js.
I've created a cube and assigned it as a child of main camera. With that structure I can rotate cube in local world with subtracting global rotation of it. Therefore it eliminates effect of camera rotation on cube, and cube remains being oriented to world coordinates.
The issue is that I am using the perspective camera and my cube is at left bottom of the screen. This creates depth at view of cube and gives wrong information about orientation of camera in world space.
Here are some view examples
Here is the method that eleminates rotation of camera.
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material =
new THREE.MeshLambertMaterial({color: 0x282828, transparent: true, opacity:
0.4});
var cube = new THREE.Mesh( geometry, material );
camera.add(cube)
this.rotationUpdate=function(){
var worldRot=cube.getWorldRotation();
worldRot._x+=offset;
worldRot._y+=offset;
worldRot._z+=offset;
cube.rotateX(-worldRot._x);
cube.rotateY(-worldRot._y);
cube.rotateZ(-worldRot._z);
debugger;
}
So my question is, how can I manipulate rotation method in a way that cube will be seen as projected on orthographic camera.
I'm using a plugin that implements 360 / VR video into our video player. It does this by using Three.js to create a sphere and taking the video itself and making it the material the sphere is created out of. The viewport is then set inside of the sphere to give it the 360 view.
The problem I'm running into is that the material is placed on the sphere using THREE.DoubleSide (THREE.BackSide would also work since we're only viewing it from the inside of the sphere), but the image is inverted since we are viewing it from the inside.
Is there a way to invert the image material that is placed on the sphere?
One way to create a spherical panorama, that is not inverted, is to use this pattern:
var geometry = new THREE.SphereBufferGeometry( 100, 32, 16 );
var material = new THREE.MeshBasicMaterial( { map: texture } );
var mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( - 1, 1, 1 );
scene.add( mesh );
It is generally not advisable to set negative scale values in three.js, but in this case, since you are using MeshBasicMaterial which does not utilize normals, it is OK to do so.
three.js r.75
I'm trying to build a simple game that shoots stuff out of a barrel of a gun. So far I have a simple group with a cube and a cylinder added as the barrel. When I rotate the group (90 degrees at a time) the barrel moves around facing different directions and that all fine.
My problem is that I cannot for the life of me figure out a way to determine which way the barrel of my gun is pointing. I need to know how to identify the face of the cube that the barrel is attached to and to what part of the 3D world it is facing..either X+, Y+, Z+, X-, Y-, Z-. Forgive me if my lexicon is all wrong in describing this. I have not posted any of my attempts because they are not working at all.
Please take a look at this CodePen for an example of what I'm trying to do...
... and here's some code just because I can't post this on SO w/o it.
var geometry = new THREE.BoxGeometry( 50, 50, 50 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
var cylgeo = new THREE.CylinderGeometry( 10, 5, 100, 32 );
var cylmesh = new THREE.Mesh( cylgeo, material );
cylmesh.rotateZ(Math.PI/2);
cylmesh.translateY(35);
var group = new THREE.Group();
group.add( cube );
group.add( cylmesh );
scene.add(group);
First, construct your "gun" so the barrel, by default, points up the positive-z axis by modifying your code like so:
cylmesh.rotateX( Math.PI / 2 );
Add a helper axis to your scene so your can see what you are doing:
scene.add( new THREE.AxisHelper( 100 ) );
In this configuration, when the parent group has rotation zero, the barrel of the gun points up the positive-z axis.
If the parent group is rotated, you can get the direction the group (and hence the barrel) is looking like so:
var vector = new THREE.Vector3(); // create once an reuse
...
group.getWorldDirection( vector );
The returned value of vector will be unit-length vector pointing in the same direction as the barrel.
three.js r.75
Relevant codepen:
http://codepen.io/OpherV/pen/yNebep
In my game I have a model of an alien tree.
For each face of this tree I generate a pyramid (CylinderGeometry with 4 faces), and position it at the center of the face. Then I wish for this pyramid to be perpendicular to the face, so that I'll get a tree with spikes.
I've tried achieving this with object.lookAt and point it at the face normal, but weird things happen. For example:
If I add
cylinderGeometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
The shape in the middle works as expected, but the rest is still distorted
What is the proper way to get my spiked tree?
Bonus question
How would I go about merging these spikes to the original geometry after proper creation and orientation so that I don't have so many separate objects?
You want to create cylinder and point it in a particular direction. One way to do that is to use the following pattern:
Create the geometry.
var cylinderGeometry = new THREE.CylinderGeometry( 1, 10, 25, 4, 1 );
Translate the geometry so the base sits at the origin.
cylinderGeometry.translate( 0, 12.5, 0 );
Rotate the geometry so the top points in the direction of the positive-Z axis.
cylinderGeometry.rotateX( Math.PI / 2 );
Create the mesh.
var cylinder = new THREE.Mesh( cylinderGeometry , characterSkinMaterial );
Objects in three.js are by default "looking" in the direction of their local positive-Z axis. (Except the camera, which looks down its negative-Z axis.)
Tell the cylinder to "look" in the direction you want. Since we have transformed the geometry, this will make the top of the cylinder point in the desired direction.
cylinder.lookAt( face.normal );
Now place the cylinder wherever you want it.
cylinder.position.copy( centerPoint );
obj.add( cylinder );
three.js r.91