Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UV Mapping fails in modern versions of Three.js #5

Open
bnolan opened this issue Mar 11, 2014 · 3 comments · May be fixed by #10
Open

UV Mapping fails in modern versions of Three.js #5

bnolan opened this issue Mar 11, 2014 · 3 comments · May be fixed by #10

Comments

@bnolan
Copy link

bnolan commented Mar 11, 2014

I've just tried this out with a modern version of Three.js and got an error around line 142...

uvs[ (3 + rotateBy) % 4 ].x = (tileU * tileUvWidth + w * tileUvWidth)

I'm guessing the mesh building code has changed in three.js and it breaks the UVs somehow - but I don't really know what I'm doing so I couldn't work out how to fix it. :( It still works if you disable uv mapping, but then the man obviously looks retarded.

@deathcap
Copy link
Collaborator

deathcap commented Apr 5, 2014

@bnolan what version of three.js, can you narrow down when it first broke? Works with at least 0.58.9 and 0.56.0 (version used by voxel-engine 0.20.1)

@deathcap
Copy link
Collaborator

deathcap commented Apr 6, 2014

Tested myself, works on 0.58.10, broken on 0.66.2 (there is a gap between these versions for three.js on NPM, didn't test in between), I suspect this is related to this change:

https://github.com/mrdoob/three.js/wiki/Migration

r59 → r60
Face4 removed. Use 2 Face3 to emulate it.

which also broke max-mapper/voxel-mesh#13 .. but minecraft-skin does not explicitly use Face4 (quads). Found this hint on http://solutiondesign.com/webgl-and-three-js-texture-mapping/:

edA-qa mort-ora-y says:
December 17, 2013 at 1:45 pm
I think it should be noted that the coordinates used for your UV are tightly coupled to the vertex arrangement created by the CubeGeometry. This may be a problem since the Cube could in theory change it’s vertex structure and break your UVs.

I also tried the code with a PlaneGeometry and sure enough it has a different face arrangement, yielding an upside-down texture. I could have figured out that exact arrangement, but to be safe I created a new geometry instead with my explicit ordering of the vertices/faces.

I'd guess CubeGeometry changed from using Face4 (quads) to two Face3 (triangles).. yep, changed in: mrdoob/three.js@44b1b3a. Then in three.js r66, CubeGeometry was renamed to BoxGeometry.

deathcap added a commit to deathcap/minecraft-skin that referenced this issue Apr 6, 2014
@deathcap deathcap linked a pull request Apr 6, 2014 that will close this issue
@lancewellspring
Copy link

lancewellspring commented May 3, 2019

I came across this issue as well. Here is my working update to a single function to make it work again:

Skin.prototype.UVMap = function(mesh, face, x, y, w, h, rotateBy) {  
  if (!rotateBy) rotateBy = 0;  
  var geo = (mesh.geometry) ? mesh.geometry: mesh;  
  var uvs1, uvs2, vCount;  
  if(geo.faceVertexUvs[0][0].length == 3){  
	  //newer versions of Three use triangles for faces  
	  uvs1 = geo.faceVertexUvs[0][face*2];  
	  uvs2 = geo.faceVertexUvs[0][face*2+1];  
	  vCount = 3;  
  }  
  else if(geo.faceVertexUvs[0][0].length >=4) {  
	  //compatibility for older versions of Three  
	  uvs1 = geo.faceVertexUvs[0][face];  
	  uvs2 = [{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0}];  
	  vCount = 4;  
  }  
  else{  
	  //might want to handle exception  
  }  
  var tileU = x;  
  var tileV = y;  
  var tileUvWidth = 1/64;  
  var tileUvHeight = 1/32;  
  var xtopleft, ytopleft, xbotleft, ybotleft, xbotright, ybotright, xtopright, ytopright;  
  xtopleft = (tileU * tileUvWidth)  
  ytopleft = 1 - (tileV * tileUvHeight)  
  xbotleft = (tileU * tileUvWidth)  
  ybotleft = 1 - (tileV * tileUvHeight + h * tileUvHeight)  
  xbotright = (tileU * tileUvWidth + w * tileUvWidth)  
  ybotright = 1 - (tileV * tileUvHeight + h * tileUvHeight)  
  xtopright = (tileU * tileUvWidth + w * tileUvWidth)  
  ytopright = 1 - (tileV * tileUvHeight)  
  uvs1[ (0 + rotateBy) % vCount ].x = xtopleft  
  uvs1[ (0 + rotateBy) % vCount ].y = ytopleft  
  uvs1[ (1 + rotateBy) % vCount ].x = uvs2[ (0 + rotateBy) % vCount ].x = xbotleft  
  uvs1[ (1 + rotateBy) % vCount ].y = uvs2[ (0 + rotateBy) % vCount ].y = ybotleft  
  uvs2[ (1 + rotateBy) % vCount ].x = xbotright  
  uvs2[ (1 + rotateBy) % vCount ].y = ybotright  
  uvs1[ (2 + rotateBy) % vCount ].x = uvs2[ (2 + rotateBy) % vCount ].x = xtopright  
  uvs1[ (2 + rotateBy) % vCount ].y = uvs2[ (2 + rotateBy) % vCount ].y = ytopright  
  if(vCount >=4){  
	  uvs1[ (2 + rotateBy) % vCount ].x = xbotright  
	  uvs1[ (2 + rotateBy) % vCount ].y = ybotright  
	  uvs1[ (3 + rotateBy) % vCount ].x = xtopright  
	  uvs1[ (3 + rotateBy) % vCount ].y = ytopright  
  }  
  geo.uvsNeedUpdate = true;  
}  

Untested on older versions of Three

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants