I am building a game. In my game is a scene where the character is reading a book. I have created pages of that book which should flip around and stuff. Using Three.js It is simple to crate a cube geo with some specs. My problem is that the paper or page representation is like a board. The paper should be floppy and flexible like paper.
That is where I am stuck. I looked into Physi.js but seems to be an overkill. Collision may be something I need in the future so that the pages do not assume the same exact plane, but for now I will settle for life-like. I looked at morphing but am unsure if that is the way to go.
I Have built a fiddle at https://jsfiddle.net/e4hqdjbz/
It is only a single page with orbit controls though.
//PAPER
frontside = new THREE.TextureLoader().load( 'https://images.pexels.com/photos/2837975/pexels-photo-2837975.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260' );
frontside.minFilter = THREE.LinearFilter;
backside = new THREE.TextureLoader().load( 'https://images.pexels.com/photos/1001780/pexels-photo-1001780.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260' );
backside.minFilter = THREE.LinearFilter;
edge = new THREE.TextureLoader().load( );
edge.minFilter = THREE.LinearFilter;
materialArray1= [
new THREE.MeshBasicMaterial( { color: 0xffffff } ), //Right side
new THREE.MeshBasicMaterial( { color: 0xffffff } ), // Left Side
new THREE.MeshBasicMaterial( { color: 0xffffff } ), // Top
new THREE.MeshBasicMaterial( { color: 0xffffff } ), // Bottom
new THREE.MeshBasicMaterial( { map: frontside } ),
new THREE.MeshBasicMaterial( { map: backside } ),
];
var geometry1 = new THREE.BoxGeometry( 23.3, 50, 0.005 );
var paper = new THREE.Mesh( geometry1, materialArray1 );
paper.position.set(0,0,0)
scene.add( paper );
Any thoughts on a direction I should head and why?
When flipping a page or paper, the animation should be more life-like, kinda flexible but not resistant. Adding physics with gravity, density and airflow may be the answer, but not sure.
Create a skinned mesh animation of the exact textured page animation, in Blender, either by you, or a 3d artist... export that animation as (gltf) .glb and load that in your app, and after the load completes, swap out the material.map s to whatever texture you want.
Related
How can I get outline affect the same as in THREE.js editor ?
I've tried this:
// child = child of my object
var outlineMaterial1 = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.BackSide } );
var outlineMesh1 = new THREE.Mesh( child.geometry, outlineMaterial1 );
outlineMesh1.position = child.position;
outlineMesh1.scale.multiplyScalar(1.05);
scene.add( outlineMesh1 );
Trying to do the same as in this example (code). I'm getting completely different effect:
Same questions: #1 and #2.
Did you try wireframe?
var outlineMaterial1 = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.BackSide, wireframe: true } );
Not sure if you would need THREE.BackSide or not.
take a look at the parameters for MeshBasicMaterial here
Have you looked at the code for the editor to see how it does it?
EDIT
I think the editor is using a BoxHelper object which creates the outline
EDIT
HERE is a stack question showing how to have the BoxHelper render on top.
HERE is a fiddle as an example implementing the above.
If you need somethink of this when user tap on mesh you can use this code :
let geo = new THREE.EdgesGeometry(intersects[0].object.geometry);
let mat = new THREE.LineBasicMaterial({ color: "black", linewidth: 10 });
let wireframe = new THREE.LineSegments(geo, mat);
wireframe.renderOrder = 1; // make sure wireframes are rendered 2nd
intersects[0].object.add(wireframe);
I have a ThreeJS scene and I'd like to provide the option of seeing all models in different modes (with or without textures and/or wireframe).
I'm trying to accomplish this using only one Geometry and one Material for each object.
When I try to remove the texture of an object by setting the map property of its material to null something bizarre happens. The object takes the latest loaded texture, even if it was loaded and applied to another object. Is this somehow an expected behavior? If not, how should I remove the map?
a good approach would be to initialize the materials you will need from the beginning :
var materials = {};
materials['lambert'] = new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.SmoothShading } );
materials['phong'] = new THREE.MeshPhongMaterial( { color: 0xFF0000, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } );
materials['basic'] = new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending } );
materials['wireframe'] = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe : true } );
and replace the material of your object when you need to :
function changeMaterial(id){
mesh.material = materials[id];
}
changeMaterial('wireframe');
I did a fiddle that demonstrates that : http://jsfiddle.net/95t964o0/75/
I did not use a material with a texture because it's a bit tricky for jsfiddle.com to load an image.
Note : be carefull when many objects share the same material! If you make changes to the material of an object it affects all the others (obviously because it is shared).
I have a code:
var urls = [ 'img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png' ];
var textureCube = THREE.ImageUtils.loadTextureCube( urls, new THREE.CubeRefractionMapping );
var cubeMaterial3 = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube, refractionRatio: 0.98, reflectivity:0.9 } );
mesh = new THREE.Mesh( wormholeGeom, cubeMaterial3 );
scene.add(mesh);
This successfully works and inserts sphere with refraction map.
But i do not using skybox, but skysphere where is whole sky represented by one texture.
Is the way to make a refraction mapping from one texture?
Not by array of six textures?
I tried many thinks (THREE.ImageUtils.loadTexture,THREE.SphericalRefractionMapping too) but no luck.
Documentation is "TODO".
This is my goal, but with one texture in skydome. There are used 6 textures in square to make sky.
is it possible to add border around a material, as attached in the image,
i can set the material color by following code
object.traverse( function ( child )
{
if ( child instanceof THREE.Mesh )
child.material.color.setRGB (1, 0, 0);
});
where object is my loaded 3d model, so am assume there should be a way to draw the border, is there any option in three.js.
As per the #shiva's comment i have tried it with the following code to draw the glow effect
if(childObject.material.name=="material4046")
{
mesh = new THREE.Mesh( globalGeomtry, material );
// mesh.visible = false
scene.add( mesh );
console.log(mesh);
// create a glowMesh
var glowMesh = new THREEx.GeometricGlowMesh(mesh);
mesh.add(glowMesh.object3d);
// example of customization of the default glowMesh
var insideUniforms = glowMesh.insideMesh.material.uniforms;
insideUniforms.coeficient.value = 2;
insideUniforms.power.value = 1.4;
insideUniforms.glowColor.value.set('red');
var outsideUniforms = glowMesh.outsideMesh.material.uniforms;
outsideUniforms.coeficient.value = 2;
outsideUniforms.power.value = 1.4;
outsideUniforms.glowColor.value.set('red');
}
now the ouput is looking as like in the second image,
i want this glow effect as the border around that material, is it is possible
I think this is what you were after. It is achieved with:
new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.BackSide } );
You can see a demo here:
https://stemkoski.github.io/Three.js/Outline.html
Source code of the demo: https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Outline.html
I tried my level best to achieve it, but unfortunately I can't get it, so I decided to do it with the wireframe option to highlight the material:
if(childObject.material.name=="material9695")
{
var mesh = new THREE.Mesh( globalGeomtry, material );
scene.add( mesh );
var outlineMaterial1 = new THREE.MeshBasicMaterial( { color: 0xff0000,wireframe : true } );
var outlineMesh1 = new THREE.Mesh( globalGeomtry, outlineMaterial1 );
scene.add( outlineMesh1 );
}
Now the wireframe is added for the material material9695 so I can identify that the material material9695 is currently selected
This is not the exact answer I expected but it is enough right now after some hard hours
I want to create a wheel from cylinder (because importing 3D models makes it slower). But I cannot use multiple materials with cylinder geometry. It uses only the first material in an array.
var geometry = new THREE.CylinderGeometry(this.diameterWheel/2,this.diameterWheel/2,this.lastikGenisligi, 20, 4);
var materialArray = [];
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x000000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( '../textures/wheel.png' ) }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x0000FF }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0xFF0000 }));
var material = new THREE.MeshFaceMaterial(materialArray);
var mesh = new THREE.Mesh(geometry, material);
What I want to create is a wheel which will have wheel.png wheel image on upper and bottom sides and black coverage on between them.
You need to loop through each face on the cylinder and tell which of the array materials the face uses.
geometry.faces[a].materialIndex = b;
Where a is the face index. You need to figure out yourself which face is which to choose the correct material through some system, ie. faces 0-10 with one color, etc. This depends on the cylindergeometry parameters. And b is the material index.