Keep up with the amazing progress that we’ve made with Multicore Rendering in RIFT with this latest update from Lead Rendering Engineer Ben “ZorbaTHut” Rog-Wilhelm!
As many of you know, we’ve been working hard on upgrading Multicore Rendering. Now that we’ve implemented improvements, let's talk more about multithreading as it pertains to Rendering in RIFT. Warning: a lot of this is technical talk and may not be suited to all readers – some may want to escape back into RIFT to experience the changes directly rather than read about them! For our fellow techno-geeks, let’s continue…
In terms of the code that runs on your computer, "rendering" can be roughly split into two parts; "deciding exactly how to render stuff" and "sending those render commands to the graphics card." Both of these tend to be expensive, and RIFT, as with most other games, used to do all of that work in a single thread. Note that while I'm dividing this into two parts, the actual rendering process isn’t a simple matter of doing one part followed by another - the "render" process consists of both interleaved in a very complicated matter.
With the exception of the newest rendering interfaces, all modern rendering APIs effectively require developers to send render commands to the graphics card on a single thread. There's not much we can do to affect this. "Multicore rendering" therefore involves mostly the first step, but with respect to the limitation of the second step.
When you're dealing with any project the size of Rift's multicore rendering system, you have to split up the job into manageable chunks. This feature took over a year to complete and so there was a lot of complex scheduling to split it into manageable chunks.
First, we had to deal with global state. What does this mean? Every time a graphics card renders something, it needs a destination, known as a “render target”. The screen is the most obvious destination, but we frequently render to textures, for use in later render steps. (In fact, if you’re using the high-quality renderer, virtually all of our rendering is done to intermediate textures!) Our rendering system assumed that the graphics system would have exactly one render target at a time. This is a perfectly reasonable assumption with a single-threaded renderer, but has to be fixed for multicore, where you might have five threads all generating commands for different render targets. That information was in our core rendering module, "Renderer", which represented the device itself, handled resource allocation, and provided information about the device's capabilities. We created a new module, "Context", intended to represent the rendering state of a single thread (including the render target and many other similar chunks of rendering state), then moved thousands of lines of code from Renderer into our new Context. Our rendering system was still single-threaded, so we still had exactly one Context, but it was a necessary organizational step.
An important concept in programming is “abstraction.” Take something like DirectX. It’s designed to give developers extensive control over graphics hardware, and it succeeds, but many of the features it provides are difficult to harness directly. When a programmer sees something like this they often build a system on top of it that is easier to use and less bug-prone. Unfortunately this always introduces limitations, and so high-performance areas are sometimes built “to the metal,” avoiding the abstractions and interacting directly with DirectX for the sake of sheer speed. Since all our multithreading work took place in our abstraction layer, these “fast” areas were, ironically, now standing in the way of performance.
Some areas could be easily changed, some had to be rewritten almost entirely; Rift’s lighting code is new as of several months ago, and for weeks before that, I was running around the world flipping between the new and old system just to be absolutely certain the new system worked exactly like the old.
Finally, we could extract that third rendering step, "send the render commands to the graphics card," from the other steps. As long as we were sending render commands directly to the graphics hardware we would never be able to multithread the rest of our rendering pipeline. We essentially inserted our own layer in between the rendering subsystem and DirectX; instead of sending commands to DirectX, it would store the commands in a carefully-coded memory-dense buffer so we could stream those commands out as quickly as possible later. This took a lot of work to get right. The process ended up being rolled into the above-mentioned “Context” module; we split it into ImmediateContext, which sent commands straight to DirectX, and BufferedContext, which stored up commands for future dispatching in a rapid burst.
At this point we could change the entire renderer into “buffered” mode - processing everything in a single thread, storing all the commands in a temporary buffer, and then sending them in a batch. This was much slower than our original single-threaded mode but useful for debugging the buffering system in isolation; we've preserved that option in our debug builds all the way up to today.
The next step was to actually use these tools to split our rendering into multiple threads. That should be easy, right? After all, we've dealt with our global state, we've set up a serialization system so all our actual commands can be sent to the graphics card in the right order – we should be able to just create a pile of Contexts, aim each one at a chunk of our game, and it should just work! Well, as anyone who's tried to multithread an existing massive system knows, it's never that easy. While we had a semi-functioning renderer working quite quickly, we spent months tracking down weird timing issues, thread contention bugs, and bits of global state that we were not aware were global. This was completely expected - there's no way to do this besides trying it and observing what happens - but it was still a very long and gradual process.
As we squashed bugs, it became clear that this was also not providing the performance gains we'd hoped to see at this stage. I'm going to make up some numbers here; bear with me. Pretend that, before this change, the entire rendering system from beginning to end took 10ms, including generating the rendering commands on a single thread and sending those commands to the graphics card. After all this work, we found that we were spending about 4ms on generating the render commands across multiple threads and storing them in buffers, but then another 4ms sending those render commands out to the graphics card. This gives us a gain of 2ms, but that's not really much of a gain; perhaps a 10% framerate increase at best. We started our Multicore Closed Beta around this time to help us squash the remaining bugs, but we knew we had a lot more work to do for the Multicore update to achieve the goals we’d set.
Up until this point, we'd simply replaced our single-threaded rendering with a chunk of multicore rendering that internally ran in parallel, but returned to the main thread only when all of that processing was complete. (That's an oversimplification, but it's basically accurate.) In order to gain the performance we wanted, we'd have to start processing the next frame while still sending the rendering commands from the previous frame.
This was a pretty significant challenge. Like most games, we rendered our UI last, overlaying it on top of a finished 3d scene. However, our UI system is done within a third-party package; we have source code for it, but converting it to use our rendering abstraction would be an enormous job. Instead, we re-organized our render pathways so we rendered our UI first, onto a separate temporary buffer. Then we'd render our 3d scene, and as a final step, we'd composite our UI onto that 3d scene.
This let us continue sending render commands to the graphics card until the next frame is about halfway done, overlapping all the network communication and game state update that has to be done before rendering the next frame. In most cases, this segment takes more than 4ms, so sending our render commands to the graphics card is effectively “free” – it happens simultaneously with something else we need to do anyway. This led to the next and one of the most key changes that really started to deliver the improvements we wanted.
Rift has a step called the "scene update”.. This is where we update the positions of all objects, along with bounding boxes, animations, level-of-detail mesh states, fades in progress, and a small mountain of other tasks. RIFT has always had some elements that utilized multiple cores, and this is one of them, but it's always been limited to a single thread. Up until this point, the rest of the game was paced such that our serial scene update always finished on time, but the multicore rendering optimizations meant that aspect of RIFT needed to speed up to avoid being the bottleneck. The final improvement we made (so far!) is to do a better job of threading that scene update process. This could in theory be done in single-threadedwithout the multicore renderer mode as well, and we'll probably enable it by default for everyone once we're satisfied it works, but right now it's tied to the multicore checkbox.
Multicore is officially in “open beta” now, and is available for use by everyone. We’ve been watching stability and crash reports, and while we still see a few very uncommon issues, we’re at the point where multicore is just as stable as the old single-threaded renderer. We’re seeing performance gains ranging up to 50% (sometimes higher). We strongly recommend giving it a try1!
Note that there are issues in the low-quality renderer that currently prevent us from offering a multicore low-quality renderer; however, if you’re using the low-quality renderer, you may find the high-quality multicore renderer is actually faster - give it a shot!
At Trion, we’re always looking for ways to improve gaming experience for everyone, and this Multicore been a really productive effort. It’s exciting to see the very positive feedback from players, and hope that you’ll log in soon to try it out too!
Many thanks to all of the players who helped us Alpha test the Multicore Update – without their contribution, this wouldn’t have gone nearly as smoothly.
Ben Rog-Wilhelm, RIFT Lead Rendering Engineer
Learn all about the brand new Mind of Madness Intrepid Adventure launching May 11!
Pursue Lord Arak from the edges of the Plane of Water into the depths of madness beyond the cosmos! Battle your way through evil deities whose insane nightmares empower Lord Arak and learn undiscovered secrets behind this most mysterious of foes.
Face Pagura the Destroyer of Dreams, the ever-hungry Fauxmire, the Tenebrean goddess Lady Envy, and many more. Each boss is more fearsome than the last, culminating with the Arisen Lord Arak himself! In between each deity, experience all-new adventures and complete quests to help further your goal of defeating the dark lord.
The fortunate Ascended who prevail in these new challenges will be rewarded with mighty equipment featuring the same iconic appearances as those found within the Mind of Madness raid. All who behold your awesome visage will know you have bested enemies of untold power to achieve such grandeur.
All Ascended have a hand in preserving Telara for future generations – help us support Hotfix Earth in the real-world with our down-to earth Bundle from April 22-25th!
This Earth Day, RIFT has partnered with Hotfix Earth, a non-profit organization focusing on responsible environmental issues. They actively educate and promote renewable practices and recycling, with a special focus on clean water systems. Check out what they actually do with your donations here!
RIFT is proud to offer the Hotfix Earth Bundle on Earth Day and over the weekend! 50% of the revenue from this bundle will go directly to Hotfix Earth.
What’s in the Hotfix Earth Bundle? We make it fun to be environmentally responsible:
- Trent companion pet – a friendly reminder of your commitment to a healthy planet
- Trent Minion card – the ultimate in renewable resources!
- Cute Earthy critters for your dimension
- Level scaling Ascended ring
Thank you for celebrating Earth Day this weekend and EVERY day. We’ve only got one planet (so far). Let’s help it stay healthy! Join us to support Hotfix Earth - gamers on a mission to create a better future.
The Hotfix Earth bundle is available from noon, April 22, 2016 to noon, April 25th, 2016, in the RIFT Marketplace. Log in now to take advantage of this limited offer!
Trion Worlds, Inc. will donate 50% from the sale of each Hotfix Earth Bundle, worldwide (excluding Alabama, Hawaii, Massachusetts and South Carolina), between 12:00pm PST April 22, 2016 through 11:59am PST April 25, 2016. This contribution is not tax deductible. Hotfix Earth is a tax-exempt 501(c)(3) organization located at 20381 NE 30th Ave. #418, Aventura Fl., 33180.
The Planar Research Institute needs your help studying new Temporal Rifts and the monstrous mechs bursting through them!
From now until April 27, completing PRI quests or picking up Temporal Flux Vaults at the RIFT in-game store will give you access to special temporal currency. Save up to take home your very own Empyreal Walker Mount, or roll for a Black Empyreal Walker included as a rare-drop in special Temporal Flux Vaults.
Head to your local PRI representative in Meridian, Sanctum, or Tempest Bay to get started or pick up where you left off!
One of the greatest strengths of RIFT over the last five years has been its amazing community, and the stellar individuals who share their efforts with their fellow players. In celebration of 5 years of RIFT, we’re highlighting these Pillars of Telara , and this time the spotlight falls on GrimTheGamer!
Ocho: What's your name in game? Grim: Most people know me as Grimok@Wolfsbane ingame. I have a max level of every class that all have a variation of Grim as the beginning of the name.
Ocho: What class is your favorite? Grim: My favorite class is Warrior. I love playing melee and having people panic when you start attacking them in PvP because you are right in their face letting them know they are in trouble.
Ocho: How long have you been playing RIFT? Grim: Two years ago is when I first started getting serious about Rift.
Ocho: What initially got you interested in RIFT? Grim: I initially was in the Open Beta but was addicted to another game based on endgame PvP at the time. A bit over two years ago I saw a video by Bajheera showing him doing low level quests in Rift and that got me wanting to check it out again. Once I took part in the Player vs Player, I was hooked.
Ocho: What's your favorite RIFT moment? What experience do you remember most fondly in RIFT? Grim: It was in Storm Legion when I felt like PvP was at it's peak during my playtime. It felt like skill and decision making was the main deciding factor in combat rather than hitting a simple burst rotation. During that time, I used to go to the Conquest map for Steppes of Infinity and hang out on the rooftops of the structures. I had rules to my combat. If you didn't wish to fight (you are in a CQ AOE spec and can't defend yourself) then you could leave without dying as long as you didn't try to score points at the objectives. If you attacked or tried to get points, then that was telling me you wish to fight me to the death. I had some of the funnest moments then with people attacking me with three of their friends, and I still won at times when people would just dance with me because they knew I wouldn't attack if they didn't attempt to get the objective. Interacting with the players like that rather than just blind attacking was so much fun. I even made a video about it called Rooftop Duels.
Ocho: What made you want to create videos for RIFT? Grim: There was a moment when Tempest Warrior became very strong in PvP combat. I hadn't been in the game very long but I knew I wanted to make a video showing off how good it was before adjustments were made to the spec. I did some livestreaming of me playing Tempest Warrior and then edited the footage into a video for a Youtube montage/guide. The reception of my first video blew me away. I had over a thousand views overnight and no one even knew who I was. With so many people telling me that they learned a lot from it, I decided to make guides for players just beginning PvP. People often get intimidated by PvP combat because they can't do their normal PvE rotations in a fast-paced and ever-changing atmosphere of fighting other players so I wanted to help break that wall. The first step is always convincing people that PvP and PvE are completely different and can't be played the same.
Ocho: What's your favorite part of RIFT, why does that aspect of the game draw you in? Grim: The crowd-control in Player vs. Player combat is what really got me. In many other games you can be stunned, snared, confused, disarmed, and polymorphed over and over. It seems that the the goal in those games is to see how long they can take you out of the game rather than promoting action in the game. In Rift, the crowd control immunities are such a blessing. If you are stunned, you are immune to another stun for a short amount of time. That allows more action to happen and that makes it much more fun for me.
Ocho: How has doing videos changed how you look at RIFT? Grim: It made me see that there are so many people that need and appreciate someone willing to help put them on the right track. Many veteran players that think that people need to start at the top level like they have attained but that is not the case at all. Players new to the game need builds and guides to get them get started and not make it hard to learn. The newer players that message me saying how my videos have helped them has made me love being a part of this game even more.
Ocho: What's your favorite experience in RIFT most people miss? What should they go out and try? Grim: Make your own builds and macros for your characters! Many people read guides on the forums or watch videos like mine to play a build that they stick with for a long time. Make it your own! Use existing guides as a starting point but then change around points to other things you'd like to have more. Are you fighting other players but dying too easily with a build you got from another player? Well that player may have much better gear than you and can survive harder hits. Change the build to have more points into a tank soul. Many guides put things in macros to make it easier for people to learn but as you get more experienced you should take things out to use those abilities or spells individually. Take your build and macros into your own hands and make it work for you.
Ocho: What tips or advice do you have for someone getting started with Videos? Grim: The biggest and most important tip I could ever give is to let people see you and the passion you have for the game you are playing. The more people feel like they know you, the more connected they will feel. If you show you are passionate about the content you are creating then people will ride the wave and be passionate right with you. Secondly, I tend to keep my passion positive since negativity tends to bring people down. People generally don't want to feel worse after watching your videos. With those two tips, your channel will grow I promise. Once it grows enough, you will get people that love what you do but you will also get some haters no matter how much you try to avoid it. Let the haters hate and keep doing what you love to do.
You foundation has to be good video and audio quality. If people notice your video is hard to see because of low resolution or your voice is hard to hear then they will often quit watching within ten seconds. As you go along, always try to make your video and audio quality better. You'll notice most of the top Youtubers have crystal clear webcams and freely scream into their microphones at exciting moments without it being hard on the listeners' ears. That is due to great equipment and settings. There are cheap alternatives for those new to video-making so take advantage of the resources you have and try to get the quality as refined as possible.
Ocho: What would you like to see for the next 5 years of RIFT? Grim: People often watch my videos and think that I'm all for separation of PvP and PvE but that isn't the case. I would like to see it taken to a much more grand scale. I'd love to see large scale PvP that might open dungeons for PvE players. Maybe PvE players could kill raid bosses and that would unlock high favor granting warfronts. It'd be nice to see us all work together for common goals!
It’s time to celebrate our fifth Anniversary, and that means Carnival is live!
Here are the new additions to Carnival:
Carnival Instant Adventure: Boglings are running wild and terrorizing the citizens of Tempest Bay. Taking inspiration from some of the Ascended’s greatest enemies, many of these Boglings present a greater challenge than their humble origins might suggest. Battle it out to prevent their rebellion, lest Tempest Bay fall to these malicious malingerers.
Frogs and… Artifacts?!?! Everyone loves to gather shinies, but you have to be extra-dexterous when they’re half-artifact, half-frog. Catch these antsy amphibians to acquire all new artifact sets!
Battle in Shimmersand: 4 exciting new Story Raid Rifts allow you to face off against the most fearsome foes ever to threaten Telara including Maelforge, Laethys, and the Teth himself!
Minion Madness: A whole new Minion Adventure Chain awaits, with unique Minion rewards, starting with the Zephyr Minion Card from the RIFT Store.
…of course there’s more! We’ve got new Daily Quests, a new Story Quest Line, and more rewards than you can shake a stick at (like the gorgeous new Carnival Capes). It’s Carnival; you know you’re going to have fun!
Enjoy five new Souls, one for each Calling, with the Ascended Souls DLC!
Explore all new options with five exciting additions to your Soul arsenal!
Warchanter (Warrior): A healing soul equipped with enchanted commands to keep your target in the fight. Make your targets Stand Tall with a Bond of Brotherhood!
Runeshaper (Cleric): Crush your enemies with runes inscribed in pure magic, and empower your allies with Greater Runes with a variety of beneficial effects. The Runeshaper Soul is both a crushing damage dealer on its own, and a benefit to your allies!
Frostkeeper (Mage): This potent single target healer utilizes magical shielding around their allies to assist in all their endeavors. Picking the right shield for the right ally is half the challenge!
Maelstrom (Primalist): Fusing the powers of fire and water, a Maelstrom is capable of dealing enormous damage while staying at extreme distance. Learn to react to developments in fights to take the Maelstrom to the next level!
Shadeborn (Rogue): Cunning and deadly, the Shadeborn harnesses the powers of Death itself to battle multiple enemies simultaneously. With a Shadeborn at your back you don’t have to worry about splitting damage between multiple targets, you just have to worry about keeping them happy!
Enjoy the latest additions to Telara while we celebrate five fantastic years together!
Get ready to party Ascended, the Update you’ve been waiting for is available NOW:
Faster Framerates: Multicore Beta keeps getting better, with new upgrades to keep improving your performance. If you haven’t tried it yet, now is definitely the time to experience the best RIFT performance for RIFT yet!
Bigger Festivities: Carnival gets all new additions, with new Story Rift Raids, Dailies, Artifacts, Rewards, a whole new quest line, the Frogifact game, and its own Instant Adventure! Starting on April 14, and running for 3 weeks, Carnival is an absolute blast!
All New Souls: The Ascended Soul Pack contains 5 new Souls, one for each Calling. Enjoy all new abilities with the Warchanter (Warrior), Runeshaper (Cleric), Frostkeeper (Mage), Shadeborn (Rogue), and Maelstrom (Primalist). We’re not just adding new souls - we’ve also got an array of updates for many of our existing Souls!
…Much More: Whether it’s PvP improvements, Patron Quests, or the incredibly gratifying new Daily Reward Calendar, there’s more than we can list in any one (or 10) blogs. Log in today or check out the patch notes!
The Celebration of the Ascended has arrived, enjoy it!