how to see Custom 2D shape on both side in three.js - javascript

I'm new to three.js and 3d programming in general,I used the three.js draw a Sector,I can the object in one direction ,but i can't see it in the opposite direction,it seems that the three.js examplehere have the same phenomenon,how can i see the object in both dretions?
var squareShape = new THREE.Shape();
var arc = 1/6*Math.PI
var len = 20
squareShape.moveTo( 0,0 );
squareShape.absarc( 0, 0, 20, 4/3*Math.PI, 5/3*Math.PI, false );
squareShape.moveTo( 0, 0 );
var geometry = new THREE.ExtrudeGeometry( squareShape, {amount:0.1} );
var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: 0xff0000 ,opacity: 1.0} ), new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true, transparent: true ,opacity: 1.0} ) ] );
mesh.position.set( 10, 10, 10 );
mesh.rotation.set( Math.PI/2, 0, Math.PI/2 );
scene.add( mesh );

In your case, it would be
new THREE.MeshLambertMaterial( { color: 0xff0000, opacity: 1.0, side: THREE.DoubleSide } )

Related

Two material in the same place in three.js

I'm trying to put two materials in a plane, one over the other. I mean, I have a bricks background and over it I need to put another material whit other texture.
Use the following approach to apply more than a single material to a mesh. The idea is to define BufferGeometry.groups in a way such that the entire geometry (not just parts of it) is rendered with different materials.
var renderer, scene, camera;
init();
render();
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setClearColor( 0x000000, 0.0 );
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, 1000 );
camera.position.set( 15, 20, 30 );
scene.add( camera );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
controls.minDistance = 10;
controls.maxDistance = 50;
scene.add( new THREE.AmbientLight( 0xffffff, 0.1 ) );
var light = new THREE.PointLight( 0xffffff, 1 );
camera.add( light );
var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
geometry.clearGroups();
geometry.addGroup( 0, Infinity, 0 );
geometry.addGroup( 0, Infinity, 1 );
// textures
var loader = new THREE.TextureLoader();
var map = loader.load( 'https://threejs.org/examples/textures/decal/decal-diffuse.png', render );
var normalMap = loader.load( 'https://threejs.org/examples/textures/decal/decal-normal.jpg', render );
var material1 = new THREE.MeshPhongMaterial( {
color: 0xffffff,
specular: 0x222222,
shininess: 100,
map: map,
normalMap: normalMap,
alphaTest: 0.5,
visible: true
} );
var material2 = new THREE.MeshNormalMaterial( {
opacity: 0.5,
transparent: true,
visible: true
} );
mesh = new THREE.Mesh( geometry, [ material1, material2 ] );
scene.add( mesh );
}
function render() {
renderer.render( scene, camera );
}
body {
margin: 0px;
}
canvs {
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/examples/js/controls/OrbitControls.js"></script>

How add texture to a three.js after it has gone throught a CSG.js process?

This my code:
var materialNormal = new THREE.MeshNormalMaterial();
var cubeGeometry = new THREE.CubeGeometry( 20, 500, 1000, 1, 1, 1 );
var cubeMesh = new THREE.Mesh( cubeGeometry );
cubeMesh.position.set(-50, 60, 0);
//scene.add(cubeMesh); //Meu
var cubeBSP = new ThreeBSP( cubeMesh );
var cubeGeometry = new THREE.CubeGeometry( 90, 90, 90, 1, 1, 1 );
var mat = new THREE.MeshBasicMaterial({color:0xffffff, shading: THREE.FlatShading, overdraw:0.5});
var cube3Mesh = new THREE.Mesh( cubeGeometry, mat );
cube3Mesh.position.set(-50, 60, 0);
//scene.add(cubeMesh); //Meu
var cubeOutroBSP = new ThreeBSP( cube3Mesh );
// Example #1 - Cube subtract
var newBSP = cubeBSP.subtract(cubeOutroBSP);
var newMesh = newBSP.toMesh(materialNormal);
newMesh.position.set(-180, 60, 0);
scene.add( newMesh );
How do I add texture to the object that was generated by subtraction?
The mesh returned by three.CSG is like a default three.js mesh where you can apply a material with a texture to.
In your example this would be newMesh, so do:
var texture = THREE.ImageUtils.loadTexture('yourtexture.jpg');
var material = new THREE.MeshPhongMaterial( { map: texture } );
//...
var newMesh = newBSP.toMesh( material );
newMesh.position.set(-180, 60, 0);
scene.add( newMesh );

Three js Add plane to the scene

I am trying to add a plane to the scene but if I check children's scene nothing is added.
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffff00, opacity: 0.25 } ) );
plane.visible = true;
this.scene.add( plane );
try this:
var geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
var mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
var plane = new THREE.Mesh(geo, mat);
scene.add(plane);
if you want to use the plane as a floor, you have to rotate it.
plane.rotateX( - Math.PI / 2);

How to rotate world axis around a different point other than the origin?

I am modelling a room in three.js and I want to rotate the camera around the middle of the room. At the moment the camera only rotates around the origin. I am not sure if the camera needs to be moved or if the world needs to be translated. The coordinates system needs to stay on the positive side as I got to show various objects that will be streamed from a server.
I would also like to move the room around. I know I need to do some translation, but I cannot find how to do it. Some calls to translation just distorted the perspective of the room more than move it.
var renderer,
scene,
camera,
controls;
renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild( renderer.domElement );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x000000, 1.0 );
scene = new THREE.Scene();
//build room
var room = buildRoom(500, 500, 500);
scene.add(room);
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(250, -500, 500);
camera.up.set(0.16608561365563415,-0.25348683041890424, 1.5868711339427681);
camera.lookAt( new THREE.Vector3( 500, 500, 000 ) );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 0.8;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
animate();
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
function buildRoom( xlen, ylen, zlen ) {
var axes = new THREE.Object3D();
//put x lines
axes.add( buildAxis( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( xlen, 0, 0 ), 0xFF0000, false ) ); // +X
axes.add( buildAxis( new THREE.Vector3( 0, ylen, 0 ), new THREE.Vector3( xlen, ylen, 0 ), 0xFF0000, false ) ); // parallel +X
//y lines
axes.add( buildAxis( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, ylen, 0 ), 0x00FF00, false ) ); // +Y
axes.add( buildAxis( new THREE.Vector3( xlen, 0, 0 ), new THREE.Vector3( xlen, ylen, 0 ), 0x00FF00, false ) ); // prallel+Y
//z lines //are four
axes.add( buildAxis( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, zlen ), 0x0000FF, false ) ); // +Z
axes.add( buildAxis( new THREE.Vector3( xlen, 0, 0 ), new THREE.Vector3( xlen, 0, zlen ), 0x0000FF, false ) ); // +Z
axes.add( buildAxis( new THREE.Vector3( 0, ylen, 0 ), new THREE.Vector3( 0, ylen, zlen ), 0x0000FF, false ) ); // +Z
axes.add( buildAxis( new THREE.Vector3( xlen, ylen, 0 ), new THREE.Vector3( xlen, ylen, zlen ), 0x0000FF, false ) ); // +Z
return axes;
}
function buildAxis( src, dst, colorHex, dashed ) {
var geom = new THREE.Geometry(),
mat;
if(dashed) {
mat = new THREE.LineDashedMaterial({ linewidth: 3, color: colorHex, dashSize: 3, gapSize: 3 });
} else {
mat = new THREE.LineBasicMaterial({ linewidth: 3, color: colorHex });
}
geom.vertices.push( src.clone() );
geom.vertices.push( dst.clone() );
geom.computeLineDistances(); // This one is SUPER important, otherwise dashed lines will appear as simple plain lines
var axis = new THREE.Line( geom, mat, THREE.LinePieces );
return axis;
}

How can I put two different textures on the front and back of a plane?

PRoblem: i'm trying to create (just for fun) a simple poker card (with a card back and a card front).
I have two different images, for back and front.
I easily created a Plane geometry with a single texture for both sides, but i really don't know how to assign a texture for a side and the other texture for the other side...
i tried this (without success :( ):
var textureBack = new THREE.ImageUtils.loadTexture( 'images/cardBack.png' );
var textureFront = new THREE.ImageUtils.loadTexture( 'images/cardFront.png' );
var material1 = new THREE.MeshBasicMaterial( { map: textureBack } );
var material2 = new THREE.MeshBasicMaterial( { map: textureFront } );
var geometry = new THREE.PlaneGeometry( 90, 110, 1, 1 );
geometry.faces[ 0 ].materials.push( material1 );
geometry.faces[ 1 ].materials.push( material2 );
var card = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial());
any help, please? :)
Was searching for solution without duplicating all my geometry.
Here you go ladies and gentlemen...
var materials = [new THREE.MeshBasicMaterial({map: texture, side: THREE.FrontSide}),
new THREE.MeshBasicMaterial({map: textureBack, side: THREE.BackSide})];
var geometry = new THREE.PlaneGeometry(width, height);
for (var i = 0, len = geometry.faces.length; i < len; i++) {
var face = geometry.faces[i].clone();
face.materialIndex = 1;
geometry.faces.push(face);
geometry.faceVertexUvs[0].push(geometry.faceVertexUvs[0][i].slice(0));
}
scene.add(new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials)));
BOOM a Two Faced Plane for ya, the loop will also work with geometries with more faces, replicating each face and applying the BackSide texture to it.
Enjoy!
You need to place two plane geometries back-to-back.
First, create a geometry for the front.
var geometry1 = new THREE.PlaneGeometry( 90, 110, 1, 1 );
Now create another geometry for the back.
var geometry2 = new THREE.PlaneGeometry( 90, 110, 1, 1 );
Spin it 180 degrees.
geometry2.applyMatrix( new THREE.Matrix4().makeRotationY( Math.PI ) );
After you load the materials, create the meshes, and add them as children of a "card" object.
// textures
var textureFront = new THREE.ImageUtils.loadTexture('images/cardFront.png' );
var textureBack = new THREE.ImageUtils.loadTexture('images/cardBack.png' );
// material
var material1 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: textureFront } );
var material2 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: textureBack } );
// card
card = new THREE.Object3D();
scene.add( card );
// mesh
mesh1 = new THREE.Mesh( geometry1, material1 );
card.add( mesh1 );
mesh2 = new THREE.Mesh( geometry2, material2 );
card.add( mesh2 );
You'll have an easier time with this if you use WebGLRenderer.
Fiddle: http://jsfiddle.net/mdAb7/11/
Updated to three.js r.69

Categories