jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Hi, I'm investigating on the GC with the CPU profiler.I get rid off the closure that was in th SPS setParticles() code, just in case closures were the cause of the memory allocations. Nothing changed. Here is an very simple example : http://www.babylonjs-playground.com/#2KSQ1R#20 As you can see, there is no animation : a SPS is built, then setParticles() is called each frame. Particle positions are just set before to an initial random position with initParticles(). That's all. To exonerate computeNormals() and computeWorldMatrix(), they aren't used in this example, so they can't have effect on the GC. I even tried to get rid off the rotation matrix computation : nothing changed, same GC activity. This looks like something deeper in BJS allocates memory... unless I can't see something obvious in my own code. Well, this is not the point of this post.In the example, if you rotate the cam and carefully look at the cubes, you will notice the z-sort is not correct.All the cubes are just little parts of a single big mesh. So I don't understand why the z-sort isn't correctly applied/updated here. Any idea ? [EDIT] : for the computeNormals + GC side, I just ran this old test for minutes on my computer http://jerome.bousquie.fr/BJS/computeNormals/optimized.htmlno GC is triggered !So the problem seems to have another source. Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 I think I almost solve the GC problem (from my own code, not BJS internals ) The z-sort problem remains ... Quote Link to comment Share on other sites More sharing options...
jahow Posted June 29, 2015 Share Posted June 29, 2015 Hey Jerome, About the z-sorting issue: since you use mesh.hasVertexAlpha = true; in the SolidParticleSystem.buildMesh method, your global mesh is recognized as alpha-blended and thus, no writing in the depth buffer is done. You cannot have semi-transparent objects AND depth writing, sadly. What could be done is sorting all the particles by distance to camera, in the case of semi-transparent particles. Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Gotcha !!!! Thank you Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 @Jahow : you were totally right.Disabling the mesh.hasVertexAlpha gives back a correct z-sort. About sorting all the particles by distance from the camera in this very case only (hasVertexAlpha = true), I don't really understand how it is possible as we have only one mesh here.Maybe re-sorting the mesh indices array, it is to say reorganize the whole mesh geometry, each frame would do the job, if we assume the first faces (indice triplets in the array) declared will be drawn before the last... not even sure.And it would be a very expensive extra-pass since particles can have different shapes in the SPS : need to sort things and set them back in the same array with potentially different stride for each particle index. Arrg So, I think I will remove the hasVertexAlpha valued to true by default. Everyone will then set it as he needs, knowing the rule you said : "You cannot have semi-transparent objects AND depth writing, sadly." Maybe, later, I will add, only for this case, the kind of sort you just talked about... but I have no idea how to do it because of the single mesh issue. Quote Link to comment Share on other sites More sharing options...
jahow Posted June 29, 2015 Share Posted June 29, 2015 You're right in that it would mean reorder the indices array. Also that would require rebuilding completely the geometry buffers each frame. It is not unrealistic in terms of performance, but may be hard to code, I don't know (I'm not familiar enough with the SPS code). Rewriting the buffers each frame is really not that uncommon. That's what the base BJS particle & sprite systems do after all! Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Ok, I'll probably give a try ... later. The only difficulty is to manage a different stride per particle in the indice array. Well, headache on debug I suppose the distance particle.position/camera.position would be a good criterium to reorder particles... I mean, without taking care about each particle size (because they can different also) Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Hi (again) people, here is a first setParticles() optimization : http://www.babylonjs-playground.com/#2KSQ1R#21 The GC has been drastically decreased in the CPU profile on my computer. Only four integer variables (indexes) are now used in this function.FYI, the best gain was got when deleting a that (that = this;) variable needed by a closure. The closure itselft had no real effect on the GC, but the that variable usage had one (don't know why). In this example, you've got 200 cubes and 200 torus knots slowly rotating according to their initial random position in space. No normal recomputation each frame and no vertex alpha.The GC here, in a local example (outside PG) is profiled at 3% max. What I learnt from this : if a function is to be called in the render loop, it is better to avoid the maximum temporary local variables, even scalar values.If you have to choose between accessing a value through a property this.foo.bar.x many times or store this value once var x = this.foo.bar.x and then to use many times this variable, you should choose the first solution.Indeed the per property access cost seems lower than the GC variable cleanup cost once the render loop has started. iiceman 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 just for fun ... http://www.babylonjs-playground.com/#2KSQ1R#22 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Ok, I just found where (I guess) the other temp variable allocations are. In the setParticles() method, I need to call, for each vertex of each rotating particle the Matrix.RotationYawPitchRollToRef() method.This method calls itself two other methods (toRotationMatrix() and Quaternion.RotationYawPitchRollToRef() ) which both create many temporary variables : https://github.com/BabylonJS/Babylon.js/blob/master/src/Math/babylon.math.ts#L1680 https://github.com/BabylonJS/Babylon.js/blob/master/src/Math/babylon.math.ts#L1557 Leads :add a condition to compute the (numerous) vertex rotation matrices only if the particle rotation is different from zero (won't change anything for rotationg particles)orreimplement all that stuff Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted June 29, 2015 Share Posted June 29, 2015 Do you plan to keep it as an extension? Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Don't know... It harder than I tought so far (because of the very good ideas from Fenomas and Jahow) and I'm fighting with the JS code.Not sure I will have the energy to port it to TS then ...Maybe if I really can achieve it (this means : the expected features and the best local optimization), I will feel proud and then will port it. Don't reall know for now Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted June 29, 2015 Share Posted June 29, 2015 Keeping it as an extension is perfectly fine for me (just need a little doc though:)) Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 it is already documented : https://github.com/BabylonJSX/SolidParticleSystem Wingnut 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 now the billboard mode works for solids alsono PG now, I'm leaving, but you can use the last PG if you want to play : I pushed the last SPS lib on-line [edit] done here : http://www.babylonjs-playground.com/#2KSQ1R#23setParticles(true);line 74 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted June 29, 2015 Share Posted June 29, 2015 Hi Jerome! Good stuff! Why use addTriangles? PS.addPolygons(100, 10, 3); PS.addTriangles(100, 10); Don't these two lines do the same thing? Just curious. http://www.babylonjs-playground.com/#2KSQ1R#24 ------------------ Also... hmm... maybe PS.addPolygons(100, 10, 3, material); ? In that demo, where are the particles getting their diffuseColor from? In another demo... http://www.babylonjs-playground.com/#2KSQ1R#25. I tried using the particle .color... a color4:PS.initParticles = function () { var fact = 120; for (var p = 0; p < this.nbParticles; p++) { this.particles[p].position = new BABYLON.Vector3((Math.random() - 0.5) * fact, (Math.random() - 0.5) * fact, (Math.random() - 0.5) * fact); this.particles[p].rotation = new BABYLON.Vector3(Math.random(), Math.random(), Math.random()); this.particles[p].color = new BABYLON.Color4(Math.random(), Math.random(), Math.random(), 1); } };That didn't work so well. Thoughts? (thx) Maybe use .material instead of .color? *shrug* Performance hell? Quote Link to comment Share on other sites More sharing options...
jerome Posted June 29, 2015 Author Share Posted June 29, 2015 Hey Wingy, The explanation about the difference between triangles, quads or any other polygons : http://www.html5gamedevs.com/topic/15154-mesh-based-particle-system/?p=87217 [EDIT] moreover a triangle is only one face (triangle) and a quad only two faces whereas a 3 vertex polygon is 3 faces, a 4 vertex polygon is 4 faces, etc. It has a real effect when dealing with thousands of particles. You can set a Color4 to each particle of course, the alpha channel will be taken in account as usual by activating : PSP.mesh.hasVertexAlpha = true;Maybe, I did a bug on color feature when refactoring the lib, I'll check tomorrow. It used to work so far. Wingnut 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 30, 2015 Author Share Posted June 30, 2015 @Wingy : color bug fixed ! It was my fault, I set color.x, y, z, w properties (as for Vector4) in the SPS code instead of color.r, g, b, a properties You can have evolving colors if you set them in the updateParticle(particle) function also http://www.babylonjs-playground.com/#2KSQ1R#27 black particles slightly getting red iiceman 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 30, 2015 Author Share Posted June 30, 2015 As it called for every vertex of every solid particles, I just added an internal Quaternion.RotationYawPitchRoll() method : https://github.com/BabylonJSX/SolidParticleSystem/blob/master/solidparticlesystem.js#L401 with no temp local variables In my local tests with the Chrome CPU profiler, the GC decreases now under 1.5 % ! Last version pushed to the link of the PG [Edit] added another tiny optimization : the quaternions are now computed only if a mesh or particle rotation if different from zero. Quote Link to comment Share on other sites More sharing options...
jerome Posted June 30, 2015 Author Share Posted June 30, 2015 Some stress tests with Chrome here :each particle has its own velocity, scale, color and rotation,measures with debugLayer I put here the limits (rounded to thousands) before it becomes lower than 60 fps plane particles : billboard mode, no normal : 3000 triangles + 1000 quads + 1000 pentagons + 1000 hexagons = 6000 plane particles facing the cambillboard mode with light reflection : 1500 triangles + 1000 quads + 1000 pentagons + 1000 hexagons = 4500 plane particles facing the cam + reflecting normal mode, no normal : 7000 triangles + 1000 quads + 1000 pentagons + 1000 hexagons = 10 K plane particlesnormal mode with light reflection: 2000 triangles + 1000 quads + 1000 pentagons + 1000 hexagons = 5000 plane particles 3D particles (I don't test the billboard mode here) : no normals : 2500 tetrahedrons + 1000 cubes = 3500 solid particleswith normals : 1500 tetrahedrons + 500 cubes = 2000 solid particles reflecting light If you then use some custom shapes with SPS.addShape(), like cylinders, spheres, torus, ribbons, whatever, the performance is directly related to the amount of vertices and indices to manage. In order to compare, we keep the same particle properties here (own velocity, color, rotation and scale) and we set the SPS in the same "mode" than the BJS particle system or the Fenomas mesh particle system.It is to say : only quads in billboard mode and no normals.The SPS here reach 10 K particles. I guess both other system do better in terms of performance.For plane particles, the SPS is slower but has a better compositing than the BJS internal one and the ability to rotate (mesh and particles), to reflect the light or to mix different shapes which are absent features in one or the other.Moreover the SPS has no integrated behavior, it is to say no emitter whereas BJS and Fenomas ones provide an emitter. You have to code it by your own here. For solid particles, I'm afraid you don't have the choice so far... have fun : http://www.babylonjs-playground.com/#2KSQ1R#28 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted June 30, 2015 Share Posted June 30, 2015 Wow, what a demo. 8 trillion things happening... in 76 lines of JS (with a bit of help from the includes) Just amazing! jerome 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted June 30, 2015 Author Share Posted June 30, 2015 and above all : just one mesh [EDIT] tested at home on my pushcart laptop : runs at 60 fps !I'm very proud of it because I know I wouldn't have succeeded to make 400 different meshes rotate and orbitate with the classical way on this computer Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted July 1, 2015 Share Posted July 1, 2015 So, now, a snow blower? (mesh blower) One meter of fresh mesh has fallen on the small Canadian village of Polygonia, Manitoba. Your job is to build the first mesh blower. errr... maybe not. Quote Link to comment Share on other sites More sharing options...
Dad72 Posted July 1, 2015 Share Posted July 1, 2015 What is this machine from another galaxy ? They could have put a hood/cap to hide the engine Wingnut 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted July 1, 2015 Author Share Posted July 1, 2015 aargg... I have a new super feature, but meanwhile I broke the billboard mode on rotating meshes and I just can't find the bugiiiiiirrrrkkkk Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.