Jump to content

Shading on Tube Mesh


adam
 Share

Recommended Posts

I don't think it has something to do with a gradient. The  standard material should not do something like that as far as I know. I think it's more about how the light gets calculated... something about the normals? I don't know enough to tell you why :P Let's wait for Jerome or somebody else who can tell you more about it ;)

 

But the effect is less visible the more tessellation you use: http://www.babylonjs-playground.com/#1A4DON#1

Link to comment
Share on other sites

No, I know why this behaves that way.

Well, it's a hard choice : the tube is done with a tubular closed ribbon. So we have two choices to close the ribbon :

- either set the last vertices at the same positions than the first ones (this is this case), so if you apply a texture, it will be stretched along the full circle. But the normals will be different on first and last vertices, so you notice this artefact (unless maybe you increase the tessellation).

- either re-use the first vertices as last ones. In this case, the normals will be continuous along the circle and no artefact will appear... but as last and first vertices are the same, they will be assigned only one uv pair... so you won't be able to stretch a texture along the complete circle. In this case, a higher tessellation will hide the texture problem.

 

This kind of problem appears with all BJS continuous closed shape : cylinder, sphere. A choice had to be done : priority to normals or to textures.

As people usually give a texture to their meshes, the priority is given to textures.

 

 

So, what are the options :

- increase the tessellation so the artefact is acceptable (or lower it if you want sharp egdes and it will be acceptable also... maybe)

or

- use ExtrudeCustom() instead with a circular shape ... and set the ribbonClosePath parameter to true. Actually this will build a tube by re-using the first and last vertices

or

- let me know people if you prefer that I change the CreateTube() code to give priority to normals over textures.

Link to comment
Share on other sites

one more parameter ? Wingy will have a heart attack !  :D

 

why not (despite it would be many parameters) ? but this wouldn't solve the other continuous closed mesh problem (sphere, cylinder) ...

 

@adam : for your PG with ExtrudeCustom, you don't need so many points in your path. I guess two only (start and stop) would be enough

Link to comment
Share on other sites

The trick is that relying on VertexData.ComputeNormals for a closed shape will inevitably produce this sort of artifact on seams (since polygons at the seams are not actually connected to each other, their normals orientations cannot be correctly interpolated).

 

BJS standard closed shapes (torus, sphere, cylinder...) have their normals set directly during mesh creation, and do not rely on ComputeNormals. As such, they avoid these artifacts.

 

Not saying there is actually a better way of doing things when it comes to ribbons... I just though it needed clarification.

Link to comment
Share on other sites

The tube (or any ribbon) is constructed as other BJS standard meshes. You've got the same artifact on a cylinder for instance :

 

http://www.babylonjs-playground.com/#1A4DON#8

 

It just depends on the choice to re-use vertices or not in the indices array.

If you re-use vertices (so the first and the last are the same vertex), then the normals are continuous and you don't have any artifact. But in this case, as only one uvs pair can set associated to this very vertex, you can't easily stretch a texture along the closed part :

example : the first vertex has uvs = [0,0]... this vertex is re-used in indices as the last vertex => its uvs is still [0, 0] and not [1, 0]

 

A workaround could be to change the way the shape are closed when building them.

Example : for a sphere you can choose to iterate first on latitudes then on longitudes or the contrary. This means the seam will etiher on a pole either on a start/end longitude. It is easier to hide a seam, reduced to one point, at a pole ;)

 

I suggested to DK an improvement (he agreed to) to computeNormals() where we could pass it an optional extra-parameter (an array) to explicitly define what vertices should be considered as other ones in the computation. So in this case, no need for vertex re-use : the normals would be computed as if they were reused for these declared vertices only. This means they could then have their own uvs each (right texture stretching) but normals computed as if they would belong to the next face.

Not sure I'm very clear.

 

But I had no time so far to code this, because it needs a deep thinking and amount of concentration :lol:

Link to comment
Share on other sites

The tube (or any ribbon) is constructed as other BJS standard meshes. You've got the same artifact on a cylinder for instance :

 

http://www.babylonjs-playground.com/#1A4DON#8

 

 

Ha, true, I thought cylinders were built like spheres and torus. You can see the use of ComputeNormals here: https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.mesh.vertexData.ts#L791

 

Spheres are fine on the other hand, see: http://www.babylonjs-playground.com/#1A4DON#9

But as soon as you use the dreaded ComputeNormals... http://www.babylonjs-playground.com/#1A4DON#10

 

I don't know, this is all pretty complicated. There must have been standard solutions found for this over the years, so some research would certainly be a good start.

Link to comment
Share on other sites

Actually the BJS sphere is particuliar case because it doesn't use the computeNormals() method.

Indeed, as we know each vertex is at radius distance from the sphere center, the normals are just set from the vertex positions themselves : https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.mesh.vertexData.ts#L647

 

So no "seam" problem here :)

Link to comment
Share on other sites

PR for ribbons ... for now

 

The closePath parameter don't make a light artifact any longer. And there is no more priority to textures over normals : both work together now (and better than 3js ;) )

 

I need to report the fix for tubes, lathes, extruded shapes... this should be quite simple (I hope)

And to report it to the mesh update method for morphing (more difficult)

Link to comment
Share on other sites

for the cylinder I took a look at the algo

 

Imho, there are two ways to do it easily :

 

- without computeNormals() , you compute the normals on each vertex when computing the positions as they do in threejs (or like for the BJS sphere): just beware of an eventual angle because top and bottom diameters could be different

- keep the algo as it is, just store  in a temporary array what vertices are the seam during the positions computation, then compute normals with computeNormals() (unchanged) and finally just change the seam vertex normal values to the average of seam start and end normal values.

Link to comment
Share on other sites

PR done: https://github.com/BabylonJS/Babylon.js/pull/623

 

I ended up reusing CreateTube with simplified parameters to create cylinders. After all, a cylinder is a subset of a tube which is a subset of a ribbon (ie parametric surface)...

http://www.babylonjs-playground.com/#1S6POH#2

 

As such, VertexData.CreateCylinder is no longer used!

 

By the way, I couldn't just ask for CreateTube to add caps to both sides, since the way it does caps is not really statisfying for a cylinder (no hard edge). IMHO, CreateTube could be enhanced by supporting hard edge at caps.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...