Jump to content

computeNormals optimization


jerome
 Share

Recommended Posts

fps is a full process measurement.  This change should have no effect on GPU time, so Potential FPS, 1000 / CPU ms (I think), is really what to measure.  On machines with very fast CPU's the improvement will be a lower % improvement.

 

On machines with fast CPU & slow GPU will see the least improvement when looking at fps.  fps is just measuring too much.

Link to comment
Share on other sites

Yep,

 

You could measure the delta time before/after the function call only, for both ones. I sometimes get x5 faster with this measure depending on the mesh size.

The FPS is affected if the function process (+the rest) is longer than 16ms or if the GC consumes CPU times for itself.

A good test could be to have a script that only calls computeNormals() each frame and absolutly nothing else.

 

 

 

You are right : the FPS is a full process measurement... but it is the one that the user is interested in  ;)

Link to comment
Share on other sites

@RaananW (which seems to be the lone IE user here ?) :

Could you stress it with large meshes for your computer in IE ? for example, get a value that gives 10 or less FPS in IE with legacy, then re-run the same value with optimized :  http://jerome.bousqu...rmals/menu.html

 

Or could you please re-test it locally without the debugLayer because differences are more visible ?

If you can't, I will probably publish next week a new page without the debugLayer.

 

 

 

No other IE testers ?  :(

Please, people, test with this link and tune it for your machine :  http://jerome.bousqu...rmals/menu.html

Link to comment
Share on other sites

it sounds well  :P

 

Another question about computeNormals() and morphing (I mean : usage of CreateXXX() on an instance of mesh in order to update it) :

 

Optimzing computeNormals() seems to be a good thing when a mesh needs to be morphed each frame. But it is still a big part in the mesh update process if you monitor the CPU profiler. The biggest part.

Some meshes don't even need to have their normals recomputed, simply because they don't reflect light and have an emissive color only, for instance.

Let's imagine I want a mesh to be animated/morphed at full possible speed and it has no light reflection but just a texture and an emissive color.

Say, a ribbon for drawing the road in a 80's OutRun like car race game.

I would like to tell my road mesh then to skip its normals re-computation each frame.

 

Something like (whatever the name, but I would prefer a name suggesting to set true to skip the computation and false  or undefined would be the default behavior, it to say to compute normals) :

// var roadPath is an array of Vector3 created before// var road is a ribbon created beforeroad.skipNormals = true;// ...// then in the render loop :roadPath = updateRoad(roadPath);road = BABYLON.Mesh.CreateRibbon(null, roadPath, null, null, null, null, null, null, road);

So my question is :

Where do I implement this new property (and what name) ?

- instanced mesh level ? abstract mesh ?

 

I could of course set this property at the object instance level only also (what I would have done in first intention).

 

This property concerns for now only mesh types which are eligible to an update with CreateXXX(). 

For now, they are only parametric shapes.

I wouldn't like to pass an extra parameter in the CreateXXX() method because it is overloaded imho ...

 

Any thoughts ?

Link to comment
Share on other sites

We can't because the initial CreateXXX() method (when used to create the mesh) automatically creates the normals by default. So there are always normals.

 

 

Do you prefer a method ? like freezeWorldMatrix() / unfreezeWorldMatrix() ?

This could be freezeNormals() / unfreezeNormals().

 

Imho, this would be coherent : advanced functions  with explicit names for advanced users who know what they want to tune deeply.

Link to comment
Share on other sites

Ok,

So what I propose is :

- on initial CreateXXX() method (mesh creation) nothing changes as we can't predict how the user will handle his mesh then.

- as soon as mesh.removeNormals() is called : the normals aren't recomputed neither applied any longer on next CreateXXX() calls (mesh update) until mesh.restoreNormals() will be called.

I could also set to whole normals array to [0, 0, ... 0] meanwhile, just in case.

 

Do you agree ?

Link to comment
Share on other sites

Hi guys!  Jerome, when you say mesh.removeNormals(), mesh is a single mesh, correct?

 

Are you saying that after mymesh.removeNormals(), all future B.Mesh.CreateXXX... won't have normals?

 

(not until mymesh.restoreNormals() is called)

 

That's seems strange.

 

What about...

 

BABYLON.Mesh.CreateWithoutNormals = true/false;

 

In this case, we are actually setting a 'mode' on our 'creators'.

 

Someday, we could do BABYLON.Mesh.CreateMode = BABYLON.Mesh.SOME_STATIC_THING;

 

(Lots of different modes for our 'creators', as necessary).

 

------------------

 

Another thought... maybe we could have two or more types of VertexData object.  If a mesh has a 'light duty' VertexData object, it has no normals.

 

Ok, that's probably a bad idea.  Just thinking... with my mostly-unaware brain.  It just seemed strange to me that a setting on a single mesh... could/would affect the behavior of all future createXXX. 

 

Maybe I misunderstood.  Thx for any clarification that can be provided... if anyone has a moment to add such.

Link to comment
Share on other sites

No, no... misunderstanding

 

When you use the CreateXXX() method (this concerns only parametric meshes : ribbon, tubes, lines, extruded shapes), it behaves normally and sets the normals on your mesh.

 

Then if you re-use the same CreateXXX() method to update the mesh, then you could choose to NOT to re-compute the normals if you don't need them (ex : a mesh with emissive color only) to gain more and more speed because ComputeNormals(), even the optimized version (PR soon), is the most consuming part of the mesh update process according to the CPU profiler (up to 90% of the update process).

 

Remember our talk about a car race game like ol'good 80's OutRun ... the road is to be updated and doesn't need to reflect the light, so we could use, say, a ribbon morphed each frame and gain process speed by setting : 

road.removeNormals();

before the render loop where the road path is updated and the road mesh recomputed and redrawn.

 

;)

Link to comment
Share on other sites

Ooopps

no, I didn't explain well.

 

I want to keep everything as it is : parametric mesh creation with normals.

 

But, if the user doesn't need them only, he could choose to skip the computeNormals() call in the mesh update process to gain more performance (because this method is always the heaviest in term of CPU usage within the update process).

 

Just like the freezeWordMatrix() : the data were computed once initially, but we don't need to re-compute them any longer each frame then for some reason.

 

So ..?

 

removeNormals() / restoreNormals() ?

or

freezeNormals() / unfreezeNormals() ?   ( <- this seems to be the most pertinent and coherent, imho )

or

skipComputeNormals() / restoreComputeNormals() ?

or

jobijoba() / gloubiboulga() ?

 

:D

Link to comment
Share on other sites

PR submitted.

 

Added freezeNormals()/unfreezeNormals() Mesh methods.

 

It concerns only ribbon based meshes : ribbons, tubes, extruded shapes.
It skips/unskips the normals recomputation on mesh update when called with CreateXXX(..., meshInstance) (the case where CreateXXX() is used to update an instance instead of creating a new one).

 

 

It improves update performances for meshes that don't need normals (emissiveColor only for instance).

 

Local chromium big ribbon (60K vertices) update test :

unfrozen normals = 35 fps

frozen normals = 60 fps

Link to comment
Share on other sites

  • 2 weeks later...

The optimization will work on any mesh using computeNormals().

 

You will really notice it on mesh updates.

 

freeze/unfreezeNormals() will work only (for now) on parametric shapes : ribbons, tubes, extruded shapes

Idem, you will notice the gain only on mesh updates.

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