Shadows
Mesh combining
-- Michiel
What exactly does it take to draw one screenful of Powargrid? Quite a lot actually, which is why I've been working on making it faster. To make the game run smoothly, we would like to redraw the screen 60 times per second. A screen redraw is also called a "frame", so it's often referred to as "60 fps". Most monitors only update 60 times per second, so faster than that doesn't really buy you anything. Simplifying a little (well... a lot), drawing the screen involves sending the geometry of everything in the scene to the graphics card, then telling it how to colour in the bits. This involves your CPU repeatedly telling your graphics card, "take this can of paint and paint that wall." Now this is magic cartoon paint: you can have plain coloured paint, checkerboard paint, grass-and-flowers paint, and it can be dull paint, glossy paint, transparent paint, etc. In computer graphics, it's called a "material". Each of these instructions to draw something using a particular material is a "draw call". Now, the graphics card is a very, very fast painter, but each draw call (changing paint cans) involves a noticeable amount of work. In short, it's much faster to paint many walls with the same paint (material) than it is to change cans for every wall. In the beginning, we were painting every object on the screen with its own can of paint. That's not just each building - each building consists of at least four legs and a body. Even though all the legs of a building have the same colour, they still got their own can of paint, so we were quickly up to thousands of draw calls, making the game run quite slowly unless you had a fast CPU. In the meantime, the graphics card was sitting there, waiting for the CPU to hand it more paint cans. The first step we took was to redo our models and make sure all the matching bits (like the legs) actually share a single material. Then, Unity can use dynamic batching to draw all the blue bits with the same paint can (one single draw call). Then, all the red bits get drawn in one go, etc. Big win! Shadows However, then we wanted to use shadows, because shadows look neat. In our case, with a single light (the sun) casting shadows, everything needs to be drawn twice: once from the viewpoint of the sun, to know which parts of the scene are in shadow, and then from the viewpoint of the camera. Unfortunately, with dozens of buildings on the play field, all consisting of several pieces, rendering shadows for all those little bits meant it was still too slow. We couldn't just rely on Unity combining the draw calls for us. We needed to draw less things! We don't actually have to leave anything out, because graphics cards are so fast these days. We just need to draw bigger chunks at a time. Mesh combining So that's what we do now: we take all the bits that make up the game grid, and combine them into larger parts that share the same material. For example, all the powered red legs get combined into one big "everything that's bright red" object. When something changes (say, a building gets blown up) we quickly rebuild the combined mesh to take the changes into account. Some details were a bit tricky, and I was occasionally looking at "the ghost of buildings past" because something had been destroyed but was still in the combined mesh, or stuff would turn invisible for a fraction of a second as the mesh was rebuilt. However, in the end it was only about 200 lines of code, and the results are nothing to sneeze at: And that's just a simple scene, at the start of the first campaign mission. Without combining objects, the CPU had to make 574 draw calls, and 733 could be prevented by dynamic batching. With combining, the exact same scene takes only 179 draw calls! So there you have it. Powargrid should run a whole lot smoother, with nice shadows, even if you don't have a very fast PC. Enjoy!
-- Michiel
0 Comments
![]() Hi everyone! My turn to write something on this here interblag, and, since I'm me, it'll be a little techy: we're gonna talk screen resolutions. This story started when one of our friends suffered through our game while having to scroll up and down continuously, because the web player window was too big for her laptop screen. Unfortunately, our budget does not currently allow us to solve this problem by sending everyone free giant monitors, so I spent some time making sure our game looks good at a variety of screen resolutions. In general, this comes down to three things:
Fitting everything in wasn't too bad, if a tight fit for some dialog boxes. And hey, limitations breed creativity, so it's good to restrict Willem in how much text he can throw at you in a single screen ;-) If your screen is bigger, the dialog boxes won't fill as much of the screen, and if it's wider, you get to see a bit more of the scenery. By default, Unity's web player plugin is set to a fixed size. For small monitors, this may be too large, so you're forced to scroll your browser window up and down to see the whole game, as was the case for our friend. If you have a huge monitor, it'll fit, but you're looking at a postcard sized game in the middle of a sea of nothingness. It was easy enough to switch that to a relative size - now the web player always takes up the full browser window. If your monitor meets our minimum supported resolution, all will be well, right? Well... There was one oversight: your browser also takes up some space with its title bar, address bar, etc. Not a problem for big screens, but small screens really need all the space they can get. However, we don't want to force the game into full screen, so the game just shows you a warning if the window ends up smaller than the recommended minimum. Full screen mode Upon adding the full screen mode, we ran into another, unrelated problem: it would use a much lower resolution than your screen could support. This thread over at answers.unity3d.com had the answer: when switched to full screen, the web player chooses its resolution by picking the smallest of these:
Failing gracefully So what if someone still tries to play the game at a lower resolution? After deciding on a minimum resolution, I had set a fixed height for the dialog windows, which caused a really bad layout problem on lower resolution screens: the dialog reply buttons would fall off the screen, leaving the player with no clue they could even do anything, effectively killing the game for them at the start of the first mission. Now, if you play the game on a low resolution screen, the game will squish everything into the available height, so you can at least see what's going on. There you go - my first blog post! A bit on the overly detailed side, but maybe the information will come in handy for someone. Not sure what I'll write about next - I'm mostly inclined to talk about the technical/coding aspects of Powargrid, so let me know if there's anything you're interested in! Happy hacking, |
AuthorWe're Michiel and Willem. Hi! Archives
June 2017
Categories |