I'm new in three.js, so I ask you for advice.
I use CubeTexture as envMap for my materials to make my objects looks like steel.
loader = new THREE.CubeTextureLoader();
this.cubeTexture = loader.load([
posXUrl, negXUrl,
posYUrl, negYUrl,
posZUrl, negZUrl
]);
...
mesh.material.envMap = this.textureCube;
And everything is ok with it but I want to make one enhancement in my scene.
The thing is that floor (negYUrl) on CubeTexture is static, but my scene assumes that floor is rotated. Unfortunately didn't find any API that allow to rotate buttom side of TextureCube instance.
Could you help me and point me on techniques that allow to do such things?
Related
I would like to build a parallax effect from a 2D image using a depth map, similar to this, or this but using three.js.
Question is, where should I start with? Using just a PlaneGeometry with a MeshStandardMaterial renders my 2D image without parallax occlusion. Once I add my depth map as displacementMap property I can see some sort of displacement, but it is very low-res. (Maybe, since displacement maps are not meant to be used for this?)
My first attempt
import * as THREE from "three";
import image from "./Resources/Images/image.jpg";
import depth from "./Resources/Images/depth.jpg";
[...]
const geometry = new THREE.PlaneGeometry(200, 200, 10, 10);
const material = new THREE.MeshStandardMaterial();
const spriteMap = new THREE.TextureLoader().load(image);
const depthMap = new THREE.TextureLoader().load(depth);
material.map = spriteMap;
material.displacementMap = depthMap;
material.displacementScale = 20;
const plane = new THREE.Mesh(geometry, material);
Or should I use a Sprite object, which face always points to the camera? But how to apply the depth map to it then?
I've set up a codesandbox with what I've got so far. It also contains event listener for mouse movement and rotates the camera on movement as it is work in progress.
Update 1
So I figured out, that I seem to need a custom ShaderMaterial for this. After looking at pixijs's implementation I've found out, that it is based on a custom shader.
Since I have access to the source, all I need to do is rewrite it to be compatible with threejs. But the big question is: HOW
Would be awesome if someone could point me into the right direction, thanks!
I need to create text with inset shadow on my object in three.js, which looks like this:
Something like ring with engraved text.
I think the easier way to do that would be to use a normal-map for the engraving, at least if the text doesn't have to be dynamic (here's how you can export a normal-map from blender). And even if it needs to be dynamic it might be easier to create a normal-map dynamically in a canvas than to actually create a geometry for the engraving.
Another option would be to actually create a geometry that contains the engraving. For that you might want to look at the ThreeCSG-library, that let's you use boolean operators on geometries: You create the 3D-text mesh, warp and align it to the curvature of the ring and finally subtract it from the ring-mesh. This should give you the ring with the engraving spared out.
In fact, I was curious how this would actually work out and implemented something very similar here: https://usefulthink.github.io/three-text-warp-csg/ (source here).
In essence, This is using ThreeCSG to subtract a text-geometry from a cylinder-geometry like so:
const textBSP = new ThreeBSP(textGeometry);
const cylinderBSP = new ThreeBSP(cylinderGeometry);
const resultGeometry = cylinderBSP.subtract(textBSP).toGeometry();
scene.add(new THREE.Mesh(resultGeometry, new THREE.MeshStandardMaterial());
Turns out that the tessellation created by threeCSG really slow (I had to move it into a worker so the page doesn't freeze for almost 10 seconds). It doesn't look too good right now, as there is still a problem with the computed normals that i haven't figured out yet.
The third option would be to use a combination of displacement and normal-maps.
This would be a lot easier and faster in processing, but you would need to add a whole lot of vertices in order to have vertices available where you want an displacement to happen. Here is a small piece of code by mrdoob that can help you with creating the normal-map based on the displacement: http://mrdoob.com/lab/javascript/height2normal/
I am using the D3-threeD2.js to translate SVG files into THREE.Shape(s) that I can then extrude with three.js. It works fine except for holes.
Lets say I have a donut shape: a disc with a hole inside. The library gives me one THREE.Shape that represents the disc and one THREE.Shape that represents the hole.
I know I can punch a hole in the disc if I have a THREE.Path, but I don't - I have a THREE.Shape.
So is there a way to get a THREE.Path from a THREE.Shape? Or alternatively is there a way to punch a hole in a THREE.Shape with another THREE.Shape?
I post here again, because I recently realized that the answer to this question is almost too simple to be true and worth mentioning separately.
THREE.Shape extends THREE.Path and you can simply use the THREE.Shape to punch a hole in another shape directly by adding it as a hole.
I tested it in two different ways. With shapes directly:
var shape = new THREE.Shape();
//...define your shape
var hole = new THREE.Shape();
//...define your hole
shape.holes.push( hole );
shape.extrude( extrusionSettings );
But if you make a path to shapes with the toShapes method it also works:
var path = new THREE.Path();
//...define your path
var shape = path.toShapes()[0];
var hole = new THREE.Shape();
//...define your hole
var holes = hole.toShapes();
shape.holes = holes;
shape.extrude( extrusionSettings );
See a fiddle here which demonstrates that both solutions work...
There is a ThreeCSG library on GitHub that you can use for performing boolean operations using Three.js meshes. That could be something for you.
The library is a bit outdated, but there are many forks that are also compatible with the latest Three.js versions.
EDIT:
I don't think it should be hard to convert your shape to a path using the points array.
var shape = ... your shape ...
var points = shape.extractAllPoints();
var path = new THREE.Path( points );
Not tested but I think it should work.
Is it possible to load an OBJ file under ThreeJS keeping the quadrilateral faces? Here is an example:
http://www.professores.im-uff.mat.br/hjbortol/disciplinas/2014.2/hwc00001/test/threejs/viewer-04/viewer-04-b.html
Note that each quadrilateral face is rendered as two triangles in wireframe. I would like to keep the original quadrilateral faces, as shown here (in Java):
http://www.uff.br/cdme/triplets/triplets-html/triplets-en.html
And what about a general n-polygon face in OBJ files? Is it possible to keep it?
Thanks, Humberto.
Unfortunately everything gets translated to triangles. However, you may be able to achieve the results you are after with this code:
var edges = new THREE.EdgesHelper( mesh );
scene.add( edges );
I'm using THREE API in order to realize some animations in my app. Now i have a real problem : i'd like making spherical rotation around a specific point. The "rotate" method included in mesh objects allow me to make them, but the center of the rotation is (by default i guess) the center of the mesh.
Then, i only rotate my objects around themself...
I have already found some examples, but they don't solve my problem. I tried to create objects 3D parents like groups, and tried to make the rotation around this groups after having translated them, but this still does not work...
Can you please give me a hand about that ?
I'm so sorry, i found my problem... Making a jsfiddle made me realize i forgot to instanciate my parent as " a new Object 3D() ", that was why i didn't see any objects in my scene when i used animation on my parent... i give you a short part of my code anyway dedicated to interested people finding any help :
// mesh
mesh = new THREE.Mesh( geometry, material );
parent = new THREE.Object3D();
parent.add(mesh);
// if i want my rotation point situated at (300;0;0)
parent.position.set(300,0,0);
mesh.position.set(-300, 0, 0);
scene.add(parent);
http://jsfiddle.net/KqTg8/6/
Thank you