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

Some material texture faces / triangles not rendering #10438

Closed
3 of 13 tasks
matisseverduyn opened this issue Dec 21, 2016 · 16 comments
Closed
3 of 13 tasks

Some material texture faces / triangles not rendering #10438

matisseverduyn opened this issue Dec 21, 2016 · 16 comments

Comments

@matisseverduyn
Copy link

matisseverduyn commented Dec 21, 2016

Description of the problem

I have a .obj and .mtl which load textures from .tga files. This all seems to work / look fine in 3D modeling software, but when loaded with three.js (THREE.WebGLRenderer({ antialias: true })) some of the object's children, (specifically between the knees and the calves, but not, for example, the pockets and legs), seem to have a transparent jagged gap / empty triangles. (Tried turning on antialiasing, changing the overdraw value, turning off transparency, etc.)

Demo project and files: demo.zip

Potential problem area: "Forgive my ignorance, but code starting at line 306 in OBJLoader.js seems to imply a fixed side limit/requirement for all faces. The obj file in question shows some faces with more than 4 sides. For example see line 60067 in the obj file. There are more after. It's as if a cut tool has healed cut seams with complex faces." - http://stackoverflow.com/users/3311552/radio

Screenshots and more details (including discussion): http://stackoverflow.com/questions/41154498/threejs-some-material-texture-faces-triangles-not-rendering/41257937#41257937

Three.js version
  • r83
  • Dev
  • r82
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
@WestLangley
Copy link
Collaborator

WestLangley commented Dec 22, 2016

OBJLoader only supports triangular faces and convex quads, and tessellates the quads for you.

If a quad is not convex and planar, then the tessellation may be incorrect.

Your work-around is to triangulate faces having more than 4 vertices before exporting.

@radio412
Copy link
Contributor

I just want to add, it's important to note from the previous discussion that Second Life Obj output is unsupported (Singularity), primitive and does not have options normally associated with obj export.

There are 3d programs which allow opening a mesh, even from SL, triangulation and re-export. Three only supports triangular faces and convex quads because most rendering hardware is designed for quads and triangles. It's nice that some viewers correct the face, but a fix in OBJLoader becomes detection and correction. There are many issues that appear in vertex sets that could be corrected as well. Unless a fix can be found at the webGL level, JavaScript intervention is out of step with performant, run anywhere ability. Strict face vertex structure is good practice for the web. 3d assets should be well considered before sent to a browser. If Three was just an OBJ viewer, it might make sense.

Since more than a few obj viewers I opened the example obj file with fixed the offending polygons, I wonder if this fix is happening at the openGL level that isn't handled by webGL. I can't imagine the number of edge cases and lazy face issues that would need to be written.

The obj specification can be read here http://paulbourke.net/dataformats/obj/ It describes no vertex limit, but I believe the assumption is that the limit is set by the render.

@mrdoob
Copy link
Owner

mrdoob commented Dec 26, 2016

Actually, we have code core that triangulates a set of points... https://github.com/mrdoob/three.js/blob/dev/src/extras/ShapeUtils.js#L192

@jonnenauha Maybe OBJLoader could use that to triangulate ngons at load time and say goodbye to this problem?

@jonnenauha
Copy link
Contributor

jonnenauha commented Dec 27, 2016

@radio412 you are referring to .obj files with polygon p declarations?

p  v1 v2 v3 . . .

    Polygonal geometry statement.

    Specifies a point element and its vertex. You can specify multiple
    points with this statement. Although points cannot be shaded or
    rendered, they are used by other Advanced Visualizer programs.

    v is the vertex reference number for a point element. Each point
    element requires one vertex. Positive values indicate absolute
    vertex numbers. Negative values indicate relative vertex numbers.

The face f afaik limits the number to four (?), which obj loader does support. Or is there a bug in that code? I have just seen that the code to handle the fourth element.

It does have this note there, but I've never seen lines with more than 4 elements on a line.

There is no space between numbers and the slashes. There may be more
than one series of geometric vertex/texture vertex/vertex normal
numbers on a line.

I believe @mrdoob is right that we could triangulate them with three.js utils. At the moment p lines I think are just ignored (or actually it might be a unhandled line exception).

@radio412 could you provide file(s) that we could use to test/implement the needed features?

@mrdoob
Copy link
Owner

mrdoob commented Dec 30, 2016

@jonnenauha The original version of the vive controller has some f with more than 4 vertices:

https://raw.githubusercontent.com/mrdoob/three.js/732fee16c12fdb53560ec791360e7899b4c3b2af/examples/models/obj/vr_controller_vive_1_5.obj

@WestLangley
Copy link
Collaborator

@mrdoob For the record, there are several places where three.js tessellates quads for the user by simply creating two triangles. The loaders come to mind.

Thing is, this is only guaranteed to work if the quad is convex. A counter-example is a V-like shape, which is, of course, not convex. In that case, only one of the diagonals is correct.

The three.js approach may also be problematic if the quad is not planar, but I do not think we need to support that case.

@andreasplesch
Copy link
Contributor

https://github.com/mapbox/earcut is a good and fast tesselation library for arbitrary 2d (flat) polygons.

@mrdoob
Copy link
Owner

mrdoob commented Jan 1, 2017

https://github.com/mapbox/earcut is a good and fast tesselation library for arbitrary 2d (flat) polygons.

Yes, we know... https://threejs.org/examples/#webgl_geometry_text_earcut

@andreasplesch
Copy link
Contributor

Just curious: is there a discussion somewhere why the built-in triangulation was not replaced ? Faster in some cases ?

@mrdoob
Copy link
Owner

mrdoob commented Jan 1, 2017

Well, at the moment, the earcut example seems to have some glitches. Not sure where these come from.

@andreasplesch
Copy link
Contributor

Oh, I see the glitches in each letter, contour. The latest earcut release has the same issue: https://rawgit.com/andreasplesch/three.js/gh-pages/examples/webgl_geometry_text_earcut.html uses the latest.

Maybe an overzealous filtering issue ? Or/And a numerical precision issue ? Maybe I can use the debugger to extract a problem contour and file an issue with earcut since I did not find a related one there.

@mrdoob
Copy link
Owner

mrdoob commented Jan 2, 2017

@andreasplesch that would be great 👌

@andreasplesch
Copy link
Contributor

andreasplesch commented Jan 2, 2017

I took a closer look.

First, turning off the bevel gets rid of the glitches:

https://threejs.org/examples/webgl_geometry_text_earcut.html#75FF00110#Earcut

That means that the glitches are probably related to the bevel functionality.

Then, after quite a bit of looking around how the triangulation of the caps could affect the bevel, I found that both the native function and PnlTri example remove duplicate start/end points:

https://github.com/mrdoob/three.js/blob/master/src/extras/ShapeUtils.js#L194
https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_text_pnltri.html#L52

It turns out that this is actually necessary not just for the triangulation but also for the bevel calculation:
https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js#L196
The getBevelVec function assumes that none of three given points are identical. Otherwise, a (0,0) translation vector is returned which causes glitches.

So, I added, similar to the PnlTri example, the removal of duplicate start/end points to the earcut example:

https://rawgit.com/andreasplesch/three.js/gh-pages/examples/webgl_geometry_text_earcut.html

And the glitches disappeared here as well. Earcut itself is actually ok with duplicate start/end points.

I can prepare a PR for the example if useful.

@mrdoob
Copy link
Owner

mrdoob commented Jan 2, 2017

I can prepare a PR for the example if useful.

Yes please! ^^

@yqrashawn
Copy link

yqrashawn commented Mar 2, 2017

#10917 Fix it, only test 2 models.

@mrdoob
Copy link
Owner

mrdoob commented Aug 10, 2017

After #11871, OBJLoader should be able to handle these files:

r86
screen shot 2017-08-09 at 8 41 57 pm

r87dev
screen shot 2017-08-09 at 8 41 38 pm

Interestingly. I realised MacOS doesn't handle ngons either... 🤔

screen shot 2017-08-09 at 8 44 52 pm

@mrdoob mrdoob closed this as completed Aug 10, 2017
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

No branches or pull requests

7 participants