I am working on importing a model into a scene using the THREE.js OBJ loader.
I know that I am able to import the geometry fine, because when I assign a MeshNormalMaterial to it, it shows up great. However, if I use anything that requires UV coordinates, It gives me the error:
[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1
I know this is because the loaded OBJ has no UV coordinates, but I was wondering if there was any way to generate the needed texture coordinates. I have tried
material.needsUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.buffersNeedUpdate = true;
...but to no avail.
Is there any way to automagically generate UV textures using three.js, or do I have to assign the coordinates myself?
The answers here are brilliant and helped me a lot. Only one thing: If you are updating vertices, do not re-assign uvs, but set them, as in (scope is my geometry):
The other answers here were a great help but didn't quite fit my requirements to apply a repeating pattern texture to all sides of a shape with mostly flat surfaces. The problem is that using only the x and y components as u and v results in weird stretched textures on vertical surfaces.
My solution below uses surface normals to pick which two components (x, y and z) to map to u and v. It's still pretty crude but it works quite well.
This function doesn't normalise the UVs to the size of the object. This works better when applying the same texture to different sized objects in the same scene. However depending on the size of your world coordinate system, you'll probably need to scale and repeat the texture as well:
This is a general version that works for spherical mapping (yaw, pitch coordinates), see example here, (look at loadSuzanne function):
To my knowledge there is no automatic way to calculate UV.
You must calculate yourself. Calculate a UV for a plane is quite easy, this site explains how: calculating texture coordinates
For a complex shape, I don't know how. Maybe you could detect planar surface.
EDIT
Here is a sample code for a planar surface
(x, y, z)
wherez = 0
: