Unity's Universal Render Pipeline performance problem? (2D) - c#

I never got real answer for this. I open this new empty project (total blank but with one GameObject)
I ended up getting 2500FPS, alright? Makes sense. The moment I install URP and then you know place in the graphics asset. BAM 1100FPS. What's going on? I put lights, well FPS keeps on decreasing. Wasn't this supposed to be better than the normal standard pipeline? If I can't do this, what are the other ways to make these optimized lights? What can I do for it?
P.S. I have been using since LWRP and then recently changed to URP. It's been at least a year, I feel like I cannot make my own game using these lights and I don't know what to do with it. This is the performance loss after just installing it, think when you have to add logic? Well, that is bad. Do I look for certain settings for this?

If your game is running above 60FPS you are OK. you do not have to worry about performance at this stage. Add assets according to your game design, tweak your scene with lights, Unity offers my tools than can improve the performance of the game. But I suggest you do profiling after you build something concrete.

You shouldn't really look at frame-rate for profiling, you need to look at the time per frame not the FPS count. Remember that the FPS is logarithmic, not linear. 2,500 FPS is a frame render of 0.4ms where 1,100 FPS is 0.9ms. The difference in this time is so small that it's almost not worth comparing. Also, target should be 60 - 144 FPS (depending on screen refresh-rate) which is a frame-time of 16.67ms - 6.9ms.
Also you need to remember that URP is forward-rendered which means the cost of each light in the scene goes up dramatically vs in Deferred in Standard.

Related

Ways to optimize conditional?

I'm making a game in Unity3D and am currently creating an AI for the enemy. The enemy needs to walk around and search for the player without running into walls.
The enemy always moves forward on it's local z-axis until it encounters an obstacle or the ray made by Raycast hits an object. When the Raycast hits an object that is part of the environment it then Raycast in all 7 directions diagonally, side-to-side and front-to-back to check for more obstacles near it as shown in this image.
The path it takes is then determined by whether or not these rays hit another object and go in the direction in which a ray didn't hit anything and that is the most optimal direction.
By most optimal I mean in the order:
fl OR fr
l OR r
bl OR br
b
I need to decide based on this data which direction to turn. If in a case where say fl and fr are both true then I would randomly decide between the two directions.
I want to optimize this process so I don't have to use multiple if-statements. I had thought of using bitmasking techniques since there are 8 directions, if you include forward, and each bit could represent a direction.
Any ideas, constructive criticism, etc is welcome. Thanks for your time.
Do not optimize pre-maturely, it is the root of all evil, as some say. This would be a perfect example.
The reason we code in C# and not in assembly (or even C) is not performance, it's readability. While it may be possible to make your code run a tiny bit faster, the results may not even be measurable. an IF branch here is still pretty tiny, and I would strongly advice against replacing it with anything else - you will loose a lot of readability, while not gaining much, if any at all performance. Bitmasking techniques start to become effective when you deal with thousands of objects (i.e. Entity), but if your if branch fits on a couple of pages, I would not touch it unless I'd find it to be a major drag by measuring it in the profiler. If you are not sure what you are doing its not that hard to make your code run slower. The priority is to make the code readable (definitely in your case as you won't be running it in a tight loop), and easy to modify. In some cases it's better to unroll the code into a more verbose if branch than to pack it into some bizarre loop - remember a loop is also an instruction.
G,day!
I have been reading a lot lately about the new path-finding system in Unity 2018. I was wondering if you had checked it out yet?
If you wanted to create it from scratch, mad props to you - however, I would be following the documentation (on the Unity website) to create an Update script on the enemy GameObject that would find the shortest path to the player GameObject's transform position, making sure to adjust for obstacles.
Have a browse around on YouTube as well - there are heaps of great tutorials.
Otherwise - if you were looking to do it on your own, the way that I would personally do it (which probably won't be the most optimal) will be though at each frame, scanning for potential paths and then finding the shortest one and acting upon it by moving the enemy based on a predetermined speed * time.deltaTime. A great visualization of the system can be found on Devon Crawford's website (link below).
Unity Documentation Link: https://docs.unity3d.com/Manual/Navigation.html
Devon Crawford's Website: http://www.devoncrawford.io/software/pathfinding

getting really bad prefomace issue in unity when trying to move more then 1000 rigidbodies in the scene

I have an object build from aprox. 1700 small cube meshes (pretty simple ones). if there are been hit i'm trying to return it to the origin a few seconds after any other objects hits it (the trigger is any other collision).
the result is between very poor performance to complety stuck.
what i tried to do so far :
limit the object to one collision trigger to avoid activation over and over again .
disable the object physics
move the object using both Physics and the transform directly.
what seems to be the problem ? can unity even handle that much objects and collisions ?
Screenshots of profiler will make easier to think a proper solution for this situation i think. I don't think any draw calls or collisions cause this problem. More about Unity3D profiler is here. You can try to handle physics in Fixed update and try different combinations of rigidbody attributes (Interpolate etc.). Goodluck.
The problem is that Physics in Unity is not a native solution. Unity uses PhysX for physics, and but of them are used like a black box so Unity doesn't know how it works under the hood. That's why all physics-based operations are complex and have rather bad performance. 1000 physics-based objects seems to much to handle by Unity3d. And it's not the only limit in Unity, for example if you create about 10 000 gameobjects (no matter which functionality they will have) they can freeze even Unity's editor.
As for a possible solution there's not much you can do:
Look through optimization guides and best practises here, here and here.
Use Unity's profiler to optimize Physics performance (try to remove physics-based "spikes")
Try to develop some system which will disable gameobject's which are not seen on scene in current moment.
Try to simplify the meshes and collider. Or try to make 1 big mesh which will split into smaller parts when you need interaction.
Try to create your own simple mathematically-based physic. I know it will be really complicated but your not universal physical solutions may have much better performance rather than PhysX.
So anyway it will be a difficult struggle.

Unity3D large maps advice - How big is too big?

Using the Unity3D engine. I'm making a multiplayer game for fun, using Unity's standard networking. If servers hold 25-50 players, what map size is recommended? How big can I make a very detailed map before it is too big for effective gameplay? How do I optimize a large map? Any ideas and advice would be great, I just want to learn and could not find anything about this on google :D
*My map is sliced into different parts.
The size of the map itself, in units, doesn't matter for performance at all. Just keep in mind that Unity (as any other game engine) uses floats for geometry, and when the float values get too high or too low, things can get funny.
What matters is the amount of data that your logic, networking and rendering engine have to churn through. These are different things, even logic/networking data, and limits on those greatly depend on architecture of your game.
Lets' talk about networking. There, two parameters are critical as your limits: bandwidth and latency. Bandwidth is how much data can you transfer, and latency is how fast. Ok, this explanation is confusing. Imagine a truck full of HDDs travelling from one city to another: it has gigantic bandwidth, and you can transfer entire data centers this way. But the latency, time for the signal to travel, is a few hours. On the other hand, two different people from these cities can hop on air balloons, look at each other in the night sky and turn their flashlights on and off. This way, they'll be able to exchange just one bit of information, but with the lowest possible latency: you can't get faster than light.
It also depends on how your networking works. RTS games, for example, often use lock-step multiplayer architecture can operate on thousands of units, but will only exchange a limited amount of data between users: their input commands. A first-person shooter, on the other hand, heavily relies on latency (which lock-stepping can damage): 10 ms when you jump and fire a rocket launcher are much more important than when you say your troops to attack. So, the networking logic is organised differently: every player's computer predicts what will happen, but the central server has authority on what actually happened. Of course, what I'm writing right now are just general examples of architectures that can be used; choosing the right way to do the networking is very difficult, but very interesting and creative task.
Now, logic itself. Actually, most of the gameplay logic used in modern games is relatively simple in terms of cpu requirements, unless it's physics or AI. Using physics in a multiplayer game is tricky enough on it's own, because of synchronisation problems (remember floats?); usually, the actual logic that can influence who wins and who loses is pretty simplified: level geometry is completely static, characters move using easy logic without real physical force, and the physics is usually limited just to collision detection. Of course, you see a lot of physical-based visual stuff: ragdolls of killed enemies falling down, rubble from explosion flying up; but these are typically de-synchronised between different computers and can't actually affect the gameplay itself.
And finally, rendering. Here, a lot of different constraints make place. To tell about them all, I would have to describe the whole rendering pipeline of Unity on different devices, and this is clearly out of scope of this question. Thankfully, there's another way! Instead of reasoning about this limit theoretically, just to a practical prototype. Put in different game assets in the scene, run it on target device and look how it performs. Adjust, repeat! These game assets can be completely ugly or irrelevant; however, they have to have the same technical properties as what you're going to use in the real game: number of polygons, sizes of textures, shaders, etc, etc. Let's say, for example, that you want to create a COD-like multiplayer shooter. To come up with your rendering requirements, just put in N environment models with N polygons each, using NxN textures, put in N characters with some skeleton animations with N bones, and also don't forget some fake logic that would emulate CPU-intenstive stuff so your perfomance measuring will be more realistic. Of course, it won't give you a final picture, but it'll be a good way to start, and it's great to do that before you start producing a lot of art assets.
Overall, game perfomance optimisation is a very broad and interesting theme, and it's impossible to give a precise answer to such a question.
You can improved this reducing the clipping plane of your camera to reduce the visible render distance, and too can use LOD improvement making your sliced part with minor details.
Check this link for more detail about LOD:
http://docs.unity3d.com/Manual/class-LODGroup.html
If you need more improvement you can make a script to load terrain in runtime based on a distance arround your player.
First and foremost: Make the gameplay work, optimize it later. Premature optimization is a waste of programmer's time.
Secondly: think of Skyrim and Minecraft. The world is separated into pieces that are loaded in background when you move around. Using that approach (chunking your world into pieces) you can have virtually infinite world size.

WPF Poor Performace for static scenes with very small dynamic content

I have a simple scene with 64 ModelUIElement3D elements, every element3d Model is a model group with 8 simple geometries, every geometry contains 3 materials, diffuse, specular and emissive.
All materials use Solid Brushes since are the fastest.
The geometries, specular material and diffuse material are Freeze to improve performance.
The only thing not freeze are the emissive materials which I’ll be updating the brush with solid brushes periodically.
When I run the application and change the brush for only one emissive material from the 1536 materials in the screen (64*8*3) the performance goes down really really bad, and the FPS go down from 60 to 15FPS.
Even I have the solid brushes in a dictionary so they are cached and created once.
This change in the brush is to make the material “blink” (really it is a fast fade-in/fade-out) in the screen. The brush change in the emissive material is every 20ms.
I see changing the brush for one material or 500 materials doesn’t make any the difference in the performance.
I comment the line where I update the brush and I get a consistent 60FPS, when I uncomment the line the FPS goes down to +/-15FPS, tried 3 different machines, 4 cores/2 Cores, very good graphic cards or medium, almost doesn't make a difference, always between 15-25 FPS.
I’m using “Performance Profiling Tool for Windows Presentation Foundation” to measure the performance, and HW IRTs per frame doesn’t go above 1 at any moment. I see when I check the checkbox “dirty-region update” that the whole scene is render every 20ms just changing the brush for one small material.
I read that WPF viewport3d doesn’t support dirty region, so I’m assuming that the whole scene is render for a minimum change.
If that is the case, is there something I can do to improve that? Since I need to create an static scene with several thousand UIElements and 10 thousands materials, but the changes are going to be so minimal so I was expecting a good performance.
If the WHOLE scene is rendered every time without chance to do anything then it is useless think on WPF to create dynamic content and I have to go for another much more complex approach as DirectX.
Please any hint how to make this work is appreciated, since I can't believe it is not possible with WPF and is some mistake on my part.
Basically I need a big scene with minimal changes, those changes happen frequently in the order of 5 to 20ms and still get the 60FPS since there are few triangles material that really change.
Thanks,
Gustavo.
I cannot give a direct solution to your question. But here's some clue:
1536 materials seems too much for the simple business charting oriented WPF 3D. It is even necessary to carefully optimize if you used low-level API like Direct3D, because down into the graphics driver architecture it will hit the batching bottle-neck, especially for DirectX 9 level driver interface.
To get best performance, the only solution is to optimize case by case with low-level graphics API, with the knowledge of graphics hardware quirks. But for a high-level general purpose 3D API, it is simply not realistic to optimize for every case. It has make some assumption, e.g. the common usage should be navigating a static scene. So that it can optimize and cache the optimized command queue to get best performance. But if the scene is changed, the cache will be invalidate and thus need to re-build and re-optimize. So it is not the size of the viewport that caused FPS drop, but the optimization.
Usually, there's hinting mechanism, by which you tell it which sub-scene-graph changes while which is static, so that to help the underlying optimization. But it is only a hint. There are many cases which make it not viable to honor the hint. And it is hard to tell the cause because the internals are encapsulated.

How does XNA timing work?

How does XNA maintain a consistent and precise 60 FPS frame rate? Additionally, how does it maintain such precise timing without pegging the CPU at 100%?
While luke’s code above is theoretical right the used methods and properties are not the best choices:
As the precision of DateTime.Now is only about 30ms (see C# DateTime.Now precision and give or take 20ms) its use for high performance timing is not advisable (60 FPS are 16ms). System.Diagnostics.Stopwatch is the timer of choice for real time .NET
Thread.Sleep suffers the same precision/resolution problem and is not guaranteed to sleep for the specified time only
The current XNA FX seems to hook into the Windows message loop and execute its internal pre-update each step and calling Game.Update only if it the elapsed time since the last update matches the specified framerate (e.g. each 16ms for the default settings). If you want to really know how the XNA FX does the job Reflector is your friend :)
Random tidbit: Back in the XNA GameStudio 1.0 Alpha/Beta time frame there were quite a few blog posts about the “perfect WinForms game loop”, albeit I fail to find them now…
I don't know specifically how XNA does it but when playing around with OpenGL a few years ago I accomplished the same thing using some very simple code.
at the core of it i assume XNA has some sort of rendering loop, it may or may not be integrated with a standard even processing loop but for the sake of example lets assume it isn't. in this case you could write it some thing like this.
TimeSpan FrameInterval = TimeSpan.FromMillis(1000.0/60.0);
DateTime PrevFrameTime = DateTime.MinValue;
while(true)
{
DateTime CurrentFrameTime = DateTime.Now;
TimeSpan diff = DateTime.Now - PrevFrameTime;
if(diff < FrameInterval)
{
DrawScene();
PrevFrameTime = CurrentFrameTime;
}
else
{
Thread.Sleep(FrameInterval - diff);
}
}
In reality you would probably use something like Environment.Ticks instead of DateTimes (it would be more accurate), but i think that this illustrates the point. This should only call drawScene about 60 times a second, and the rest of the time the thread will be sleeping so it will not incur any CPU time.
games should run at 60fps but that doesn't mean that they will. That's actually an upper limit for a released game.
If you run a game in debug mode you could get much higher frames per second - for example a blank starter template on my laptop in debug mode runs well over 1,000fps.
That being said the XNA framework in a released game will do its best to run at 60fps - but the code you included in your project has the chance of lowering that performance. For example having something constantly fire the garbage collection you normally would see a dip in the fps of the game, or throwing some complex math in the update or draw methods - thus having them fire every frame..which would usually be a bit excessive. There are a number of things to keep in mind to keep your game as streamlined as possible.
If you are asking how the XNA framework makes that ceiling happen - that I cant really explain - but I can say that depending on how you layout your code - and what you can do can definitely negatively impact this number, and it doesnt always have to be CPU related. In the instance of garbage Collection its just the cleaning up of a RAM which may not show a spike in CPU usage at all - but could impact your FPS, depending on the amount of garbage and interval it has to run.
You can read all about how the XNA timer was implemented here Game timing in XNA Game Studio but basicly it would try and wiat 1/60 of a second before continuing the loop again, also note that update can be called multiple times before a render if XNA needs to "catch up".

Categories

Resources