Convergence Posted December 7, 2016 Share Posted December 7, 2016 Thanks to the awesome Babylon framework, I'm creating a city building and simulation game; I thought I'd share the progress so I can ask some questions in case I get stuck. Here's a sample town (read-only at the moment because the UI is far from complete): http://misc.blicky.net/c2/?id=1 (desktop only) Some screenshots.. Current issues: Shadows are way too 1990's, even though the targetTexture is 4096 in size. It would be nice if the shadowGenerator's matrix would adopt to only include faces that are in the camera frustum. That way shadows would look good from afar and close-up. Solved Road intersections are a pita. The current solution, using CSGs on the road segments (extruded shapes) and some math to create a plane is barely acceptable and rather slow/error-prone. Performance. While 'idle' FPS is not bad, when adding more structures, the browser will lag because it is using MergeMeshes() to merge the new structures to the existing meshes. I'm currently transitioning to SPS meshes, because they build a lot faster, however are also more restrictive. So my question is: why is MergeMeshes() slower than SPS.buildMesh() and can it be made to match the latters' speed? BitOfGold, Mingsen, satguru and 11 others 14 Quote Link to comment Share on other sites More sharing options...
The_dude8080 Posted December 7, 2016 Share Posted December 7, 2016 Looks really great! However I am not experienced with babylon.js... Convergence 1 Quote Link to comment Share on other sites More sharing options...
jerome Posted December 7, 2016 Share Posted December 7, 2016 The mesh you get with MergeMeshes() is a BJS standard mesh. The mesh you build with the SPS is also a BJS standard mesh. So both are the same "speed" once they are built. Only the way to build them and the associated features differ. Don't forget to dispose the meshes used as models with mergeMesh() (the same with the SPS) to free some memory. The SPS may be faster when building the final mesh because it "knows", before being built, all the model geometries to be used. Convergence 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 7, 2016 Share Posted December 7, 2016 This is TRULY impressive @Sebavan is working on cascaded shadows that can help a lot here! Dad72, Convergence and adam 3 Quote Link to comment Share on other sites More sharing options...
inteja Posted December 7, 2016 Share Posted December 7, 2016 This is great. Love it. Convergence 1 Quote Link to comment Share on other sites More sharing options...
BitOfGold Posted December 7, 2016 Share Posted December 7, 2016 @ConvergenceAbout shadows: I use a modified version of BABYLON.DirectionalLight.prototype.setShadowProjectionMatrix This sets the high detail shadow to a much smaller box shadowMesh near camera with high resolution. BABYLON.DirectionalLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList) { var orthoLeft = Number.MAX_VALUE; var orthoRight = Number.MIN_VALUE; var orthoTop = Number.MIN_VALUE; var orthoBottom = Number.MAX_VALUE; var tempVector3 = BABYLON.Vector3.Zero(); var activeCamera = this.getScene().activeCamera; var hasShadowMesh = (typeof this.shadowMesh != 'undefined'); //size shadow Map to this.shadowMesh only (local area) // Check extends for (var meshIndex = 0; meshIndex < renderList.length; meshIndex++) { var mesh = renderList[meshIndex]; if (hasShadowMesh) { //only check shadowMesh mesh = this.shadowMesh; meshIndex = renderList.length+1; } if (!mesh) { continue; } var boundingInfo = mesh.getBoundingInfo(); if (!boundingInfo) { continue; } var boundingBox = boundingInfo.boundingBox; for (var index = 0; index < boundingBox.vectorsWorld.length; index++) { BABYLON.Vector3.TransformCoordinatesToRef(boundingBox.vectorsWorld[index], viewMatrix, tempVector3); if (tempVector3.x < orthoLeft) orthoLeft = tempVector3.x; if (tempVector3.y < orthoBottom) orthoBottom = tempVector3.y; if (tempVector3.x > orthoRight) orthoRight = tempVector3.x; if (tempVector3.y > orthoTop) orthoTop = tempVector3.y; } } var xOffset = orthoRight - orthoLeft; var yOffset = orthoTop - orthoBottom; BABYLON.Matrix.OrthoOffCenterLHToRef(orthoLeft - xOffset * this.shadowOrthoScale, orthoRight + xOffset * this.shadowOrthoScale, orthoBottom - yOffset * this.shadowOrthoScale, orthoTop + yOffset * this.shadowOrthoScale, -activeCamera.maxZ, activeCamera.maxZ, matrix); }; As in this thread: I am very interested in @Sebavan 's workings on cascading shadows, Can I find something about this? I have seen an interesting thing in Godot engine, a shadow map texture with two levels, one with high detail one with large area (in one texture. on the top left white box) Convergence 1 Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 8, 2016 Author Share Posted December 8, 2016 6 hours ago, BitOfGold said: @ConvergenceAbout shadows: I use a modified version of BABYLON.DirectionalLight.prototype.setShadowProjectionMatrix This sets the high detail shadow to a much smaller box shadowMesh near camera with high resolution. Thanks This worked great. I actually tried to modify this function to do something similar, but I couldn't get it to work. But yours works great (see pic below). Also its probably faster because it doesn't have to loop through the renderList every frame. jerome and JohnK 2 Quote Link to comment Share on other sites More sharing options...
satguru Posted December 8, 2016 Share Posted December 8, 2016 awesome Convergence 1 Quote Link to comment Share on other sites More sharing options...
iiceman Posted December 8, 2016 Share Posted December 8, 2016 Are you freaking kidding me!?? OMG! This looks so good!!! Damn, that's just plain awesome!!!! How? Just how? I run into performance problems even when if I try to keep things simple... but you got so much details! I love it, great job! Convergence 1 Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 8, 2016 Author Share Posted December 8, 2016 25 minutes ago, iiceman said: Are you freaking kidding me!?? OMG! This looks so good!!! Damn, that's just plain awesome!!!! How? Just how? I run into performance problems even when if I try to keep things simple... but you got so much details! I love it, great job! Thanks Haha I know the feeling, I also had major performance problems in my first babylon projects. But here are a few pointers though that I learned over the months that increased performance a lot for me: MergeMeshes() and/or SPS for static objects is highly superior in performance to createInstance(). If I'd use instances for all the buildings/props/etc, the draw calls would be the same but the FPS would likely be < 10. This is because Babylon by default computes the matrix for every instance for every frame. mesh.computeWorldMatrix() was consistently at the top of the chrome profiler on my other scenes before I figured this out. The first point will also be also have a more drastic impact if you use texture atlases for your meshes, so even different meshes can be combined into one draw call. In case you have many meshes that move or billboard (like the cars and the lens flares in my scene) you will have to take shortcuts like only animating the cars close to the camera. The others are frozen by .freezeWorldMatrix(). Don't use .isVisible = false; rather use isEnabled(false). Don't use rays, or only one per frame. Use mesh.isPickable is false for any mesh that doesn't need interaction. Any mesh that is static, use mesh.freezeWorldMatrix(); Any material that doesn't change, use material.freeze(); however its glitchy for any mesh that is animating. Sometimes I even remove meshes from the scene.meshes array in case I need them for something (like a parent to other meshes) but they will never be visible nor will they ever move. Saves another mesh babylon will have to iterate over every frame. Use the browsers' profiler to see what functions consume the most time. Hope this helps your project(s) With all these in place I think I can fill the whole map with more buildings and foliage without running into serious performance issues, but we will see. kpgbrink, getzel, iiceman and 6 others 9 Quote Link to comment Share on other sites More sharing options...
vamos Posted December 8, 2016 Share Posted December 8, 2016 Wow, this must be the best JS game I have ever seen. It looks great! Regarding shadows, some time ago I worked on a project where we used a technique called Trapezoidal Shadow Maps. I think it's a similar idea where you add more details to shadows near the camera, but it adds a distortion (to maximize details near the camera) that you can then reverse in your shader. I couldn't give you the details of the matrix maths, but there's a good article about the technique. Convergence 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted December 8, 2016 Share Posted December 8, 2016 @BitOfGold are you interested to merge this change? Quote Link to comment Share on other sites More sharing options...
BitOfGold Posted December 8, 2016 Share Posted December 8, 2016 @Deltakosh Yes I will send a PR with this code, but I have an idea inspired by @vamos right now and I need to test it. GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
inteja Posted December 8, 2016 Share Posted December 8, 2016 @Convergence those are some great performance tips. It'd be good if they could be reviewed and added to the documentation, maybe under Tutorials > Optimizing your scene? I'd add them myself but I'm still a newbie to BJS - a little too green to be contributing to documentation. Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 9, 2016 Author Share Posted December 9, 2016 5 hours ago, inteja said: @Convergence those are some great performance tips. It'd be good if they could be reviewed and added to the documentation, maybe under Tutorials > Optimizing your scene? I'd add them myself but I'm still a newbie to BJS - a little too green to be contributing to documentation. Thanks, I'm not sure if they are universal, but they did work for me. But yes, the documentation could give .freezeWorldMatrix() and siblings some love . I also consider myself too green to poke the documentation Quote Link to comment Share on other sites More sharing options...
Nabroski Posted December 9, 2016 Share Posted December 9, 2016 4fps Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 9, 2016 Author Share Posted December 9, 2016 54 minutes ago, Nabroski said: 4fps Do you mean you are getting 4fps on the demo? If yes, may I ask what GPU you're running? Quote Link to comment Share on other sites More sharing options...
Nabroski Posted December 9, 2016 Share Posted December 9, 2016 GTX 570. I dont play games, also the people i know dont play games, this forum is the only place i know of weird people playing games. i have more a scientific and artistic interest on programming, just pushing bits. I know its a demo, looking forward for an optimized version. At least you can not do much for me. Maybe an old school fog of war effect, that saves some render. The pictures looks pretty. Good Luck. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted December 9, 2016 Share Posted December 9, 2016 I was thinking about it. Here are some thoughts, just to make users with a 30bucks pc happy. Its not Doom 3 u can create a screenshot at some point and just moving some elements (like cars) on a *.png plane, would be funny. You, the dev, only know that that is not a 3D model anymore. (Hyperrealistic Painting) Also diving everything on your map into tiles and push and pop them with user input on different layers, very easy to implement. Also async load of files. I rather wait for a .babylon file to be phrased as not seeing anything at all. Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 9, 2016 Author Share Posted December 9, 2016 6 hours ago, Nabroski said: GTX 570. I dont play games, also the people i know dont play games, this forum is the only place i know of weird people playing games. i have more a scientific and artistic interest on programming, just pushing bits. I know its a demo, looking forward for an optimized version. At least you can not do much for me. Maybe an old school fog of war effect, that saves some render. The pictures looks pretty. Good Luck. 2 hours ago, Nabroski said: I was thinking about it. Here are some thoughts, just to make users with a 30bucks pc happy. Its not Doom 3 u can create a screenshot at some point and just moving some elements (like cars) on a *.png plane, would be funny. You, the dev, only know that that is not a 3D model anymore. (Hyperrealistic Painting) Also diving everything on your map into tiles and push and pop them with user input on different layers, very easy to implement. Also async load of files. I rather wait for a .babylon file to be phrased as not seeing anything at all. Thanks I'm working on performance now.. If you have a minute, you can try to see if disabling render targets helps (click the FPS meter to open the babylon debug layer, then uncheck render targets). But I'll get a more rigorously optimized version out soon with a settings dialog to disable and enable certain options. Hmm, what FPS are you getting for this link? http://misc.blicky.net/c2/?id=1&highfps Quote Link to comment Share on other sites More sharing options...
jerome Posted December 9, 2016 Share Posted December 9, 2016 GPU : NVidia Quadro K620 CPU : Intel Xeon 4 x 3.10 GHz OS : linux Ubuntu 16.04 LTS 64b (desktop) Browser : Chrome first demo link = 20 fps second demo link (highfps) = 58-60 fps Really really really awesome and impressive ! Congratulations I noticed that you drastically reduced the number of draw calls. What is the main difference under the hood between both the scenes ? Convergence 1 Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 9, 2016 Author Share Posted December 9, 2016 35 minutes ago, jerome said: GPU : NVidia Quadra K620 CPU : Intel Xeon 4 x 3.10 GHz OS : linux Ubuntu 16.04 LTS 64b (desktop) Browser : Chrome first demo link = 20 fps second demo link (highfps) = 58-60 fps Really really really awesome and impressive ! Congratulations I noticed that you drastically reduced the number of draw calls. What is the main difference under the hood between both the scenes ? Thanks, great Disabling shadows (one of the main differences) will reduce the number of draw calls by half, since almost all meshes are in the renderList of the shadowGenerator. Additionally only reflecting the skybox instead of the city itself helps, and reducing the number of cars, lens flares and props. If I could ask one more minute of your time, how's the FPS in the second link but with shadows re-enabled (through the babylon debug layer)? edit: nice CPU btw Quote Link to comment Share on other sites More sharing options...
jerome Posted December 9, 2016 Share Posted December 9, 2016 how can I display the debug layer ? ok just found it 140 draw calls and 30 fps stable in Chrome and the DL still visible (what can consume some fps also) and it rises back to 60 fps when the scene becomes darks so maybe no shadow anymore ! really nice Convergence 1 Quote Link to comment Share on other sites More sharing options...
JohnK Posted December 9, 2016 Share Posted December 9, 2016 Just to let you know couldn't to get it to load in firefox 50.0.2 worked brilliantly in Chrome Console messages unreachable code after return statement[Learn More] roads.js:1006:1 TypeError: scene.getMeshByName(...) is null[Learn More] roads.js:543:12 Quote Link to comment Share on other sites More sharing options...
Convergence Posted December 9, 2016 Author Share Posted December 9, 2016 5 minutes ago, JohnK said: Just to let you know couldn't to get it to load in firefox 50.0.2 worked brilliantly in Chrome Console messages unreachable code after return statement[Learn More] roads.js:1006:1 TypeError: scene.getMeshByName(...) is null[Learn More] roads.js:543:12 Thanks, might just be a network error; I got that error one time also but a refresh worked for me 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.