I am creating a web app using THREE JS which contains multiple 3D view.
Here is the code flow.
Created scene.
Created camera and added to the scene
Added light to the scene.
Added WebGLRenderer.
Added 3D objects to the scene.
Removed objects added in step 3 and added 3D objects of some other view.
On repeating steps 5 and 6 several times, GPU memory shoots up and browser becomes unresponsive.
In order to clean memory in three.js. You need to call dispose function for geometry, material and texture explicitly. Here is the explanation from threejs. Hope this helps.
https://threejs.org/docs/#manual/en/introduction/How-to-dispose-of-objects
Related
I need to show a 3D model on a SceneView in my iOS app, after its relative path (String) has been loaded from Firebase and passed to my SCNScene(named: path).
The function that reads the path runs very quickly, but once I try to attach the scene to my SceneView, it takes pretty long before it can actually be displayed (5-6 sec).
The .scn file I'm trying to show is about 20MB, and if I set showStatistics = true, it says my scene contains more than 200K triangles.
I need a help in order to understand how I could strongly reduce the "loading" time of the scene.
I've already tried reducing the number of polygons and also using the SceneView method prepare(_:completionHandler:) in order to render my scene on a background thread and (ideally) speed up the process to display it, but nothing worked for me.
Any help would be really appreciated. Thanks!
I am new to ARKit. I am trying to add so many new nodes into the sceneview in front of my camera. I wanna add objects like cylinder and sphere with different colors. the problem is my frame speed will drop significantly and my phone starts to lag so much after I add 30 objects to the scene. I searched for a solution so much and I found this function to be helpful. prepare(_:completionHandler:). This was how I was adding my objects to the scene without prepare function.
self.sceneView.scene.rootNode.addChildNode(cylinder)
and now I am using the prepare function like this:
self.sceneView.prepare([cylinder], completionHandler: { (success) in
self.sceneView.scene.rootNode.addChildNode(cylinder)
})
Now frame drops like before, also the app will crash after adding 50 objects to the scene.
I think I am not using it correctly and I don't know how to use it?!
Also, I am thinking what else I can do to better my ARKit app?
How you're adding the objects is independent of the frame rate that you're seeing, and when you use all the memory available. The different method of adding objects can be useful for keeping the UI responsive, but you will need to optimize (or use more powerful hardware) when placing a lot of objects into an ARKit scene.
If you're trying to understand your ARKit performance, the medium article on ARKit 1.5 vs. 2.0 might be useful.
I'm working on an ARKit project for 4 months now.
I noticed that when adding a child to my scene rootNode, there is a FPS drop. The device freezes for less than a second.
I did a lot of research and trials, noticed that all Apple's code examples have this FPS drop too when placing an object.
It does not matter if the node is added directly (scene.rootNode.addChild(child)) or if it's added in the renderer loop at different phases (didUpdateAtTime, didApplyAnimations etc...).
I found that once an object has been added to a scene, the next added object will render immediately. I use a 3D model created in SceneKit editor, clone it to generate my different nodes before adding them as child. I do this loading work before placing the objects.
Instruments shows that the renderer loop is busy for the duration of the freeze.
The only solution that I found is to add my nodes to the scene behind a loading screen before starting the whole experience.
Is that a normal behavior in game programming to render nodes before using them ?
Thanks guys
With the release of ARKit 3.0 and its satellite – RealityKit (framework with optimised rendering engine and changed scene's hierarchy, that was written in Swift hence it has no Objective-C binding), a drop-frame, when adding a child, is reduced to an imperceptible value.
And such a predictable behaviour of ARKit3/RealityKit ligament is especially true for devices with processors A12 Bionic and A13 Bionic manufactured on 7 nm process (and, of course, due to the fact they have last-gen neural engines and powerful GPUs).
For devices with a less powerful processors (A9, A10, A11), it is advisable to use 3D models with a total number of polygons of no more than 10K per model, and with usual shaders like .blinn or .phong (not PBR).
I believe it's quite a common practice for games and apps that use game engines, to firstly load (or cache) all the necessary game assets (like 3D models, textures, sound files, etc) into RAM before using them. For further details please read this article and this article.
However, it’s worth saying that AR games, unlike VR games, consume considerably more processing power, therefore they need to be carefully optimised. So, you're absolutely right, rendering nodes before using them and it's a normal behaviour in game programming.
My project runs at 55-60FPS on an iPhone 6 but anything older is completely unplayable because something is eating CPU.
I think the issue is related to the number of tiles and layers on my map (64x256 with 4 layers) and Instruments shows "SKCRenderer:preprocessSpriteImp(..." taking 5198ms (23.2%) running time.
Does JSTileMap load every single tile's image (visible or not) at once? This post from RW indicates that is the case and that it could be worked around for large performance boosts:
http://www.raywenderlich.com/forums/viewtopic.php?f=29&t=9479
In another performance note - Sprite Kit checks all it's nodes and
decides which ones it needs to display each frame. If you have a big
tile map, this can be a big performance hit. JSTileMap loads all the
nodes (SKSpriteNode for each tile) when it loads the tile map. So, I
was also seeing performance issues in the Sprite Kit version with my
maps (which are 500 x 40 tiles). I added a check to my version of
JSTileMap that's included in the kit that marks the hidden property of
each tile, then intelligently unhides and hides only the tiles that
enter/exit the screen space. That increased performance on these
larger maps significantly.
Unfortunately that post does not go into detail regarding the steps taken to remedy this.
My first thought was to (I'm a beginner, please be gentle) create an array of nodes by looping through each point and checking for a tile on the specific layer. From there I'd work on adding/removing them based on distance from the player.
This didn't work, because the process of adding nodes to an array simply caused the app to hang forever on larger maps.
Could someone lend a hand? I'd love to work with larger/more complicated tilemaps but this performance issue is destroying my brain.
Thanks for reading!
UPDATE: Big thanks to SKAToolKit: https://github.com/SpriteKitAlliance/SKAToolKit
Their culling feature solved my problem and I'm now running even larger maps at less than 35% CPU.
JSTileMap has some issues handling larger maps but you do have a couple of options to consider:
Break your large map into several smaller pieces and load each new piece as required.
Only load those objects which are in the player's vicinity.
Only load those tiles which are in the player's vicinity.
I personally found it impossible to accomplish #3 with JSTileMap as I could not locate an array holding the map tiles. I solved this issue by using the SKAToolKit which provides easy access to map tile arrays. It is an excellent resource for parsing maps created in Tiled.
I have seen the usage of plist and png atlasses for the game i am developing. However I've notice a slight performance swiftness(speed up) keeping the 60 fps, and for a side note my app has not crash at the moment.
The thing is I noticed I have used SpriteFrameCache with plist to do CCactions and animations for my characters(sprites). However some of the characters ive been using SpriteBatchnode, but it was on accident, since I am relatively new to deep development of a game, I didnt notice this difference before, they both work, but I feel like both are the same, its just that one has an easier way of implementation than the other, i was thinking that perhaps it was developed in an earlier version....
so my question is. is there a difference between the two? will my game benefit for using SpriteFrameCache over SpriteBatchNode?
Thanks for the help.
FYI: this doesnt slow down my developing, its just a question because I know at the end when my game is finished maybe i would want to optimize performance for my game.
Batch nodes draw all child sprites in one draw call.
Sprite frames hold a reference to a texture and define a region in the texture to draw from. The cache allows you to access sprite frames by name.
Both are different concepts, they are not replacements for each other. You can use sprite frames to create sprites or sprite frame animations. In addition to that sprite batching enables you to speed up rendering of two or more sprites using the same texture.
Note that if you use a batch node with only a single child sprite this will not be any different from rendering the sprite without the batch node, since both create a single draw call so there is no positive effect in using the batch node.