Changing scale of mesh changes lighting brightness of scene? - three.js

I needed to refactor my custom mesh creation a bit
from:
create mesh of unified sizes (SIZE,SIZE,SIZE), than scale them as needed (setting scale for each axis)
to:
create mesh with correct size, do not scale later
meshes are custom generated (vertices, faces, normals, uvs), nothing of this process was altered, worked like a charm before
=> resulting meshes are the same size, position, etc.
The whole scene setup stays the same: lights, shadowing, materials, yet when using the second approach the whole lighting is very very bright and super reflective, is that a known issue?
material used is MeshPhongMaterial with map, bumMap, specMap, envMap
using three.js r68, no error/warning in console
before:
https://cloud.githubusercontent.com/assets/3647854/3876053/76b8f260-2158-11e4-9e96-c8de55eaec9a.png
after:
https://cloud.githubusercontent.com/assets/3647854/3876052/76b7fa86-2158-11e4-9393-8f3eece04c0b.png

Did you rescale the normals in the mesh?
The mesh format probably needs normalized normals, in which case, the new normals are now incorrect, but would've been correct, if you hadn't rescaled.
Alternately, you say the lights haven't been changed, maybe they need to be appropriately redirected in the scene. (Assuming you're applying different scaling factors in each axis.)

Related

ThreeJS Texture fit UV Map

I'm tring to developing a configurator. It's about cups. These should be displayed in 3D. A design should be uploaded. It works by uploading a texture like this.
Otherwise the design will not fit. Is there a way to load a full-size rectangular image as a texture? The Texture may like to be stretched. The texture should not be made cubic by the user, but automatically in the background maybe.. I hope you understand me.
This is the OBJ-File
Your UV mapping looks difficult to apply a texture to. Especially because it has so much empty space, and is skewed in an arc, so you would need to warp all your textures for them to fit nicely.
You should make the UV mapping work for you. Why don't you use the built-in CylinderBufferGeometry class to apply a texture on top of your cup geometry? You could use its attributes to match the side of your cup's shape:
CylinderBufferGeometry(
radiusTop,
radiusBottom,
height,
radialSegments,
heightSegments,
openEnded,
thetaStart,
thetaLength
);
With this approach, you could leave your cup geometry untouched, then apply a "sticker" texture on top of it. It could wrap all the way around the cup if you wanted, or it could be constrained to only the front. You could scale it up, rotate it around, and it would be independent of a baked-in UV mapping done in Blender. Another benefit is that this approach occupies the entire [0, 1] UV range, so you could simply use square textures, and you wouldn't be wasting data with empty space.
Look at this demo to see how you can play with the geometry's configuration.

Applying translation, rotation and scale to THREE.BoxGeometry(..)

I am creating a scene with several thousand cubes, each of which can be translated, scaled and rotated.
Initially, I tried creating a cube geometry, applying the transformations, creating a mesh with my material and adding it to the scene. That worked but was very slow because of all the draw calls.
So now, for all the cubes, I create a THREE.BoxGeometry(1,1,1), and merge it with a single THREE.Geometry() each time before finally creating a material and a single mesh and adding it to my scene.
The performance is drastically improved but I don't know how to apply a translation (XYZ), scale (XYZ) and rotation (quaternion) to each box before merging it. Can someone point me at the right syntax?
Secondly, if I merge my geometry like this, is there still a way to pick out a single box with a raycaster? Typically I've used the object name on the mesh but that's not relevant anymore.
Thank you.

Multiple Textures on a Single Face/Plane

If I have a geometry, say
THREE.PlaneGeometry(400,400);
or
THREE.MeshBasicMaterial({map:new THREE.MeshFaceMaterial(materials)});
//multiple textures on only one face
How would I make it so that I have multiple textures on the same side of the plane?
Furthermore, how would I go about setting the coordinates of the texture and position of the texture on the Plane (or face)?
It should look something like this:
You can use shader material with textures as uniforms or look other approaches there, there and there.

Three.js Merge objects and textures

My question is related to this article:
http://blog.wolfire.com/2009/06/how-to-project-decals/
If my understanding is correct, a mesh made from the intersection of the original mesh and a cube is added to the scene to make a decal appear.
I need to save the final texture. So I was wondering if there is a way to 'merge' the texture of the original mesh and the added decal mesh?
You'd need to do some tricky stuff to convert from the model geometry space into UV coordinate space so you could draw the new pixels into the texture map. If you want to be able to use more than one material that way, you'd also probably need to implement some kind of "material map" similar to how some deferred rendering systems work. Otherwise you're limited to at most, one material per face, which wouldn't work for detailed decals with alpha.
I guess you could copy the UV coordinates from the original mesh into the decal mesh, and the use that information to reproject the decal texture into the original texture

Fixed texture size in Three.js

I am building quite a complex 3D environment in Three.js (FPS-a-like). For this purpose I wanted to structure the loading of textures and materials in an object oriƫnted way. For example; materials.wood.brownplank is a reusable material with a certain texture and other properties. Below is a simplified visualisation of the process where models uses materials and materials uses textures.
loadTextures();
loadMaterials();
loadModels();
//start doing stuff in the scene
I want to use that material on differently sized objects. However, in Three.js you can't (AFAIK) set a certain texture scale. You will have to set the repeat to scale it appropiate to your object. But I don't want to do that for every plane of every object I use.
Here is how it looks now
As you can see, the textures are not uniform in size.
Is there an easy way achieve this? So cloning the texture and/or material every time and setting the repeat according to the geometry won't do :)
I hope someone can help me.
Conclusion:
There is no real easy way to do this. I ended up changing my loading methods, where things like materials.wood.brownplank are now for example getMaterial('wood', 'brownplank') In the function new objects are instantiated
You should be able to do this by modifying your geometry UV coordinates according to the "real" dimensions of each face.
In Three.js, UV coordinates are relative to the face and texture (as in, 0.0 = one edge, 1.0 = other edge), no matter what the actual size of texture or face is. But by modifying the UVs in geometry (multiply them by some factor based on face physical size), you can use the same material and texture in different sizes (and orientations) per face.
You just need to figure out the mapping between UVs, geometry scale and your desired working units (eg. mm or m). Sorry I don't have, or know a ready algorithm to do it, but that's the approach you probably need to take. Should be quite doable with a bit of experimentation and google-fu.

Resources