ThreeJS Cube texture strange visual - javascript

I'm having a strange visual effect (don't know how to call it) in my project. I've made a cube and made it possible to rotate. Below I got the code which creates the cube.
Also see the image. If I upscale my segmentsWidth and segmentsHeight it's kinda gonna look better on the side, but on the front the lines will not be straight. The image is made with the code shown below. What I would like to see is the lines at the front straight and side ways it should not have a V in it.
If I have the overdraw = false than I will see white lines which I don't want but don't got a messy picture. But when I set it to true I will have a messy picture.
Is this possible?
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 250;
scene = new THREE.Scene();
// Cube
var geometry = new THREE.CubeGeometry( 100, 200, 8, 1, 1 );
cube = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial([
new THREE.MeshBasicMaterial({ color: 0xefefef }),
new THREE.MeshBasicMaterial({ color: 0xefefef }),
new THREE.MeshBasicMaterial({ color: 0xefefef }),
new THREE.MeshBasicMaterial({ color: 0xefefef }),
new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('img/door.jpg'),
overdraw: false
}),
new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('img/door.jpg'),
overdraw: false
})
]));
cube.position.y = 150;
scene.add( cube );

This is a well-known issue with CanvasRenderer.
An excellent description of the issue can be found in the last half of this post.
Your best solution is to increase the tessellation of your geometry.
var geometry = new THREE.BoxGeometry( 100, 200, 8, 2, 2, 2 );
P.S. Notice there are 6, not 5, args to this constructor.
EDIT: updated for three.js r.67

Related

Three.js 3D models are not looking well and clean

I am working on 3D Modelling using Thrre.js , and have to display neat and clean product after reading a .DAE file but my product display is not well clean and good . Can anybody please help me , i have also given the light sources but still product shown are very dull .Actual product to be shown
My product image render screen shot , no leather is shown in product and also very dull
I am trying following Code :
<script>
var renderer, scene, camera, controls, light;
var geometry, material, mesh;
init();
animate();
function init() {
document.body.style.cssText = 'margin: 0; overflow: hidden' ;
renderer = new THREE.WebGLRenderer( { alpha: 1, antialias: true, clearColor: 0xffffff } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 50000 );
camera.position.set( 100, 100, 100 );
//camera.position.set(-15, 10, 15);
controls = new THREE.TrackballControls( camera, renderer.domElement );
scene.add(camera);
light = new THREE.AmbientLight(0xffffff, 10);
light.position.set(100,100, 100).normalize();
scene.add(light);
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 10, 10).normalize();
scene.add(light);
var pointlight = new THREE.PointLight(0xffffff, 1, 0);
pointlight.position.set(50, 100, 50)
camera.add(pointlight);
scene.add(pointlight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10,10,10);
scene.add(spotLight);
var pointHelper = new THREE.PointLightHelper(pointlight, 0.1);
scene.add(pointHelper);
this.renderer.render(this.scene, this.camera);
geometry = new THREE.BoxGeometry( 10, 10, 10 );
material = new THREE.MeshLambertMaterial( { ambient: 0x333333, color: 0x888888, opacity: 0.000001, transparent: true } );
// material = new THREE.MeshLambertMaterial({ color: 0xffffff, vertexColors: THREE.FaceColors });
mesh = new THREE.Mesh( geometry, material );
mesh.name = 'basic template mesh';
mesh.visible = false;
scene.add( mesh );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
controls.update();
}``
Through this code , i got the very dull product.
Can Anyone Please help me to sort out this problem ?
You are using the wrong material. The MeshLambertMaterial is used for diffuse surfaces, those that do not have specular highlights (paper, raw wood, cloth). You need to use the MeshPhongMaterial which allows the specular highlights (white spots) in the chair.
In your model, you have two types of surface: leather and wood. Even though both of them have specular highlights, their shininess are different. You will have to define separate materials for both surfaces. But, since I see you have a single object, this can be difficult. You can define a single MeshPhongMaterial for both surfaces, but you will have to try several values in the parameters to get the desired effect.

How to render many images on a cube side and define their position like a gallery wall?

I'm trying to build a gallery wall via three.js. So far I succeeded rendering an image on each side like this:
I've put paintings on left and right. However, I want to render more images on each wall rather than filling the entire wall with a single image. Something like this:
How can I set arbitrary positions?
Here's my code:
var scene = new THREE.Scene()
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1,1000)
console.log(window.innerWidth, window.innerHeight)
var renderer = new THREE.WebGLRenderer()
renderer.setSize( window.innerWidth,window.innerHeight)
document.body.appendChild(renderer.domElement)
//keep object in view when resize window
window.addEventListener('resize', () => {
let width = window.innerWidth
let height = window.innerHeight
renderer.setSize(width, height)
camera.aspect = width / height
camera.updateProjectionMatrix()
})
controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.enableZoom = false
controls.enableRotate = true
controls.enablePan = false
var geometry = new THREE.BoxGeometry( 2.5, 2, 4 )
var cubeDice = [
new THREE.MeshBasicMaterial({ color: 0x666666, side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({ color: 0x666666, side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({ color: 0x999999, side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({ color: 0x999999, side: THREE.DoubleSide }),
new THREE.MeshPhongMaterial({ map: new THREE.TextureLoader().load('img/h5_1993.132.jpg'), side: THREE.DoubleSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('img/unnamed.png'), side: THREE.DoubleSide }),
]
// var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } )
var material = new THREE.MeshFaceMaterial(cubeDice)
var cube = new THREE.Mesh( geometry,material )
scene.add( cube )
// //set camera closer
camera.position.z = 1
var update = function(){
cube.rotation.y += .005
}
var render = function(){ renderer.render(scene, camera) }
var GameLoop = () => {
requestAnimationFrame(GameLoop)
update()
render()
}
GameLoop()
MeshFaceMaterial does not do what you want. It makes each image fill up an entire face (an entire wall).
To make separate, movable images on the wall, it would be better to make an individual smaller mesh for each image, and then position them very close to the wall. That way the image can cover the entire mesh, but not cover the entire wall:

Change color of one face of the cube - THREE.js

I am learning OOP while using Three.js. I know, a hard way to do it. So i created a box in the scene. Now i want to change color of one face of that cube.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 100, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(5, 5, 10);
var geo = new THREE.BoxGeometry(5,2,5);
var mat = new THREE.MeshBasicMaterial({color:0xff0ff0, side:THREE.DoubleSide});
var mesh = new THREE.Mesh( geo, mat);
scene.add(mesh);
//Right there i want to chance color of the face. Its not working
mesh.geometry.faces[5].color.setHex( 0xffffff );
var edge = new THREE.WireframeHelper( mesh, 0x00ff00 );
scene.add(edge);
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.render(scene, camera);
EDIT: the reason it did not work for me was the color i used 0xffffff. This program will work unless color is 0xffffff.
In your case, if you want to change the color of one face of the cube, you will need to specify vertexColors in your material.
var geo = new THREE.BoxGeometry( 5, 2, 5 );
var mat = new THREE.MeshBasicMaterial( { color:0xff0ff0, vertexColors: THREE.FaceColors } );
var mesh = new THREE.Mesh( geo, mat );
mesh.geometry.faces[ 5 ].color.setHex( 0x00ffff );
The rendered face color will be the specified face color tinted by the material color.
If you change a face color after the mesh has been rendered at least once, you will have to set:
mesh.geometry.colorsNeedUpdate = true;
three.js r.80

Wrapping a torus with a spiral

I'm trying to create the effect similar to hula hoop covered in tape using three.js.
The 3d model should end up looking something like below.
I can create the hoop in 3d space using TorusGeometry with the ability to pan around, but I have not managed to work out how to get a 2nd TorusGeometry to break into sections.
What is the best way of creating this effect?
// hoop
hoop = new THREE.TorusGeometry(20, .5, 100, 50);
var hoopMaterial = new THREE.MeshPhongMaterial({
ambient: 0xffffff,
color: 0x028fde,
specular: 0x555555,
shininess: 0
});
hoopMesh = new THREE.Mesh(hoop, hoopMaterial);
hoopMesh.position.z = 0;
scene.add(hoopMesh);
hoopTape1 = new THREE.TorusGeometry(20.1, .6, 0, 50);
var hoopTapeMaterial = new THREE.MeshPhongMaterial({
ambient: 0xffffff,
color: 0xDE5102,
specular: 0x555555,
shininess: 0
});
hoopTape1Mesh = new THREE.Mesh(hoopTape1, hoopTapeMaterial);
hoopMesh.position.z = 0;
scene.add(hoopTape1Mesh);
jsfiddle with current working code.
You will have to apply a texture to your torus that is seamless to achieve that effect. The texture should be similar to this one:
Then use this code pattern:
var geometry = new THREE.TorusBufferGeometry( 6, 0.4, 16, 64 );
var loader = new THREE.TextureLoader();
var texture = loader.load( 'stripe.jpg', function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 16, 0.5 ); // or whatever you like
render();
} );
var material = new THREE.MeshPhongMaterial( {
color: 0x998877,
specular: 0x050505,
shininess: 50,
map: texture
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
three.js r.77

How to increase the thickness of the extrude geometry along x and z axis - Three.js

I had created a shape using extrude geometry , and now with the extrude settings i need to increase the thickness i had used bevelThickness it increases the thickness along y axis , but need to increase it along x and z axis.
Here my working jsfiddle
Below is my code for extrude settings ,
var extrusionSettings = {
curveSegments:5,
steps: 10,
amount: 10,
bevelEnabled: true,
bevelThickness: 120,
bevelSize: 0,
bevelSegments: 8,
material: 0,
extrudeMaterial: 1
};
var geometry1 = new THREE.ExtrudeGeometry( shape1, extrusionSettings );
var materialLeft = new THREE.MeshLambertMaterial({
color: 0xd6d6d6,// red
transparent:true,
side: THREE.DoubleSide,
ambient: 0xea6767,
opacity:-0.5
});
var materialRight = new THREE.MeshLambertMaterial({
color: 0xcc49c3,//violet
side: THREE.DoubleSide,
ambient: 0xcc49c3
});
var materials = [ materialLeft, materialRight
];
var material = new THREE.MeshFaceMaterial( materials );
var mesh1 = new THREE.Mesh( geometry1, material );
object.add( mesh1 );
object.rotation.x = Math.PI / 2;
scene.add( object );
Below is sample image
is there any setting to increase it ? Can any one guide me ?
Finally i did the trick to fix it, What i did is just i cloned a Mesh add added the position to cloned mesh, so i got the wall nearby another inner wall, by this way i have added multiple clone with the loop, multiple inner wall nearby other created the wall thickens,
Demo : Fiddle
//outer wall mesh
var mesh1 = new THREE.Mesh( geometry1, material );
object.add( mesh1 );
var mesh_arr=new Array();
for(i=0.1;i<15;i++)
{
//cloned mesh,add position to the cloning mesh
mesh_arr[i] = mesh1.clone();
mesh_arr[i].position.set(i,i,i);
mesh_arr[i].updateMatrix();
object.add( mesh_arr[i] );
}

Categories

Resources