Invert material image of sphere in three.js - javascript

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

Related

three.js map mesh.geometry.attributes.uv

I am currently working on a 3D configurator.
So I should be able to import a logo on a FBX object, which normally already have UV coordinates.
The problem is : I am struggling since 3 days ago, trying to import a texture on a mesh but I can't map it using his UVs coordinates.
So, I have a texture with a logo.
When I map it on a simple Cube, no problem, it is working :
But when I try to apply the same texture to my mesh :
The texture is cropped.
So I've been looking inside the mesh json tree and I found it :
So there are uv coordinates, but it seems different from my cube because, when I look to his json, I don't find the same tree which is (on the cube) :
And finally, this is my code :
if(myMesh.name == 'Logo'){
// Texture
var texture = new THREE.TextureLoader().load('img/logoTesla_Verre_green.jpg', function(){
texture.needUpdate = true;
// Material
var material = new THREE.MeshLambertMaterial( {map: texture, morphTargets: true} );
material.needUpdate = true;
// Geometry Cube
var geometry = new THREE.BoxGeometry( 40, 40, 40 );
// Cube
var cube = new THREE.Mesh( geometry, material);
scene.add(cube);
// Duplicate logo mesh for testing
var newGeometry = myMesh.geometry;
var newMesh = new THREE.Mesh( newGeometry, material);
newMesh.position.y = 100;
newMesh.geometry.uvsNeedUpdate = true;
scene.add(newMesh);
});
}
My question is : Should I use the geometry.attributes.uv object to map my texture ? If yes, how to do that ?
Or should I convert these UV coordinates to a geometry.faceVertexUvs ???
Please, help me, I am totally lost :)
Nevermind, it has been solved by exporting the .fbx again.
Now the mapping is working fine !
But I don't know why...
Thank you for your question and answer. I was having the same problem where my custom FBX I imported was only taking the bottom left pixel of the canvas as the color for the whole mesh. (I was using texture = new THREE.CanvasTexture(ctx.canvas); to get my texture).
The issue for me was that the FBX had no UV mapping! How I solved it was I imported the fbx to maya, opened up the UV editor (under the modeling menu mode got to UV->UV editor ) then in the UV editor there was a Create section and I hit one of those options (i chose cylinder) and then exported it with the default fbx settings. I am very grateful this worked.
You can see the result of using a canvas context as a custom FBX texture here:
www.algorat.club/sweater

How to set view of an object as orthographic projection with using perspective camera?

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.

Using three.js, how do I determine which plane my mesh is facing?

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

Shadow Catcher in three.js / shadow on transparent material

I need to cast a shadow on a boxMesh while the mesh itself should be invisible.
I've found a technique on three.js GitHub Issue Tracker that's seemingly been working a few years ago but doesn't anymore - it involves the creation of a new shader.
Is there any other way or an updated version of that now not anymore working trick?
You can cast a shadow on a mesh having a transparent material by using THREE.ShadowMaterial. Use this pattern:
var material = new THREE.ShadowMaterial();
material.opacity = 0.5;
var mesh = new THREE.Mesh( geometry, material );
mesh.receiveShadow = true;
scene.add( mesh );
There is an example of its use in this three.js example.
three.js r.147

Never-ending floor in THREE.JS scene

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.

Categories