Fixed texture size in Three.js - 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.

Related

Instanced Rendering of height map applied terrain mesh/geometry

I am working in three.js to make terrain from the heightmap data that i have in json file. I now have a chunk of mesh which add up to make a complete terrain but since multiple chunk make multiple draw call which i believe is expensive and making my system very slow.
This is my code:
https://github.com/pravinpoudel/three.js-boilerplate/blob/main/src/client/terrain.ts
This is my terrain after i apply the heightmap and is of size 4104x1856 madeup from chunk of size (256, 256)
I checked the documentation and example of instanced rendering in three.js but all ask for same geometry but in my case i have deformed the y value of each vertex according to the heightmap data from elevation json file.
I believe that i can make it perform better with instanced rendering but i dont know how can i implement that with each geometry in the chunk have altered y value.
Moreover, is there anything more you can suggest?
I am learning a lot from this group and i believe that i can get more insight from here.
Thank you everyone for being here and helping people like me !!

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.

How to load part of a big texture on another texture in three.js?

I need to render a texture as a library of small parts, then copy each part to a set of different textures used in the scene. I think this is fundamental and I cannot find documentation specifically in three.js. Should I seek a solution in pure WEBGL, or is there a three.js solution?
EDIT:
One "solution" would be to set the UV coordinates of the target mesh (plane, whatever) to correspond only to the desired part of the big texture, but that would definitely be very inefficient, as it would require for each small mesh to load the whole big texture a huge waste of memory and GPU power as the whole big texture would be probably transformed multiple times(!), aside the inconvenience of setting the different UV coordinates on each mesh object.
So, I'm looking to copy and assign only a small part and occupy in memory and process only that part for each mesh.

Changing scale of mesh changes lighting brightness of scene?

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.)

Flexible texture repetition depending on object size in THREE.js

I have a question about texture mapping and repeat with THREE.js. In my scene there are several thousands of cubes with different height. All shall have the same material with a texture which shall be repeated depending on the height of the object. Since repeat.y isn't the same for each object, I'm afraid I cannot use the same material for all cubes although the texture is the same. Is that right? Or is there a way to use the same material and update the repeat value automatically?
Thank you very much in advance.

Resources