SakeTami
Afterparty
Afterparty

patreon


A "brief" note on game performance

Sup folks. I wanted to give you all some insight into my thoughts behind the performance of the game, both its current state and what I plan to do in the future to improve performance. This is mainly just rambling about some thoughts I've had on the topic but I wanted to lay them out in a somewhat cohesive way in case anyone is curious about why they aren't getting better performance or what's going on to cause that.

There are two things that are by far and away the most performance intensive features. The first is Lumen dynamic global illumination, and the second is alembic groom hair. These two features in combination become even more intense. But I do have reasons for continuing to use them, and there are still some things that can be done to drastically improve performance. 

The first thing I wanted to talk about is Lumen vs baked light setups. It's often suggested to use baked global illumination with static precomputed lighting instead of Lumen for the significant performance gain it provides. And for many projects, including my own, this is very solid advice that will improve your frames significantly. This is why the previous update used baked lighting. But using a baked light setup comes with some drawbacks. The first is the obvious fact that baking light maps takes time. ~10 minutes to bake a scene might not seem like much, but as soon as you add a new light or want to shift the positioning of lights, which I do often, you have to build again. GPU Lightmass makes it much easier to get an idea of the final light bake result without having to bake the entirety of the scene, but no matter what, if you go with baked lighting you're going to be spending a lot of time baking, and this is time that can't be spent on other features or content. 

There are things you can do to reduce the time it takes to bake lights. For example you can optimize the lightmap UVs of every model in your scene to ensure the best result when that model gets baked. Unreal will even generate these lightmap UVs for you automatically. But it's not perfect, and often it will generate UVs that are highly unoptimized and provide nothing in terms of speeding up the baking process. To fix this, you can export the models and UV unwrap them by hand with light baking in mind inside a tool like Blender. But this again takes time, on top of the time it takes to build the lighting itself. 

Another thing you can do to speed up light build times is lower the lightmap resolution of objects. Increasing the light map resolution will increase build times exponentially, but the quality of baked shadows for example will be much higher. For the best result, you need to strike a balance between the lightmap resolution of objects, the quality of the bake, optimizing the UVs, and the time it takes to bake it. 

So, between manual optimization of lightmap UVs, tweaking and iterating on the lightmap resolutions of every object in your scene for the best result, and the time it takes to build, using a precomputed light setup is overall very time consuming for this project.

But there's also the fact that according to Unreal Engine documentation, as of UE 5.3, alembic groom hair does not yet support precomputed lighting (https://docs.unrealengine.com/5.3/en-US/hair-rendering-in-unreal-engine/). This project uses groom hair, so a lighting method that doesn't fully support alembic groom makes it very difficult to justify using. 

None of this is to say solo developers can't or shouldn't use baked lighting. Many do and very effectively. But how time consuming it is depends entirely on what kind of project you're making, and for my project it is very time consuming. And so I have made the decision to stick with Lumen, even though in comparison to baked lighting it is much more intense.

Now I want to touch on the second biggest performance pitfall, which is the alembic groom hairs. There's lots of ways to do hair in games, from rigged mesh hair, to rigged hair cards, to alembic hair (which I use). I don't create hair from scratch. I use hair models from the Daz Studio asset store that have interactive licenses available. These hairs are extremely easy to convert to alembic groom for use in UE and they look very good. So naturally, as a solo developer this is an ideal route for getting high quality hair in my game.

The problem is that alembic groom hair is notoriously heavy. Even Metahumans, which are Epic's officially supported characters and very well optimized, will give you a significant performance hit just due to the groom hair alone.

But the performance of groom hairs has been improving with every new release of UE, and I suspect this will continue. You can also generate LODs for groom hair, and UE 5.3 has a "continuous LOD" option for groom hair which you can think of as sort of like Nanite but for grooms (however this feature is still experimental). I use all of these features in my game to improve the performance of hair. Despite this though, the grooms are simply heavy as hell to begin with, so while optimizing helps, at the end of the day they're simply heavy to use no matter what, and it's compounded if you have many characters using grooms on screen at once.  

On the other hand, groom hairs look very good. The hair shading model used by grooms is very simple to use and looks great. I do value fidelity in my project, so some performance sacrifice for higher quality hair is something I'm willing to do (within reason). 

But there's another option for hair too, that being hair cards, which are used in many, many popular games, and they are exponentially better on performance. Hair cards if designed well can look almost indistinguishable from grooms. But achieving that level of quality from hair cards is an entire skillset, and studios like CD Projekt Red and Rockstar have people doing this full time. So creating hair cards from scratch this way as a solo developer in a project like mine that requires many different hairstyles is out of the question. 

Fortunately though there are some decent quality hair card packs available from the UE marketplace as well as places like Artstation. And this is something I'm definitely interested in doing in the future, but it will require more research on my part to both find the best pack(s) suited for my project and the workflow to make them usable with my characters, and there's the expense of the hair card packs themselves, and the better quality ones cost a pretty penny (subscribe to my Patreon and this can happen faster >:O). But rest assured I'm very open to this approach, and if it turns out to be a viable replacement for grooms that would instantly resolve one of the biggest performance hogs in the game.

In the meantime though while I'm looking into hair cards, the game will continue to use both Lumen and alembic groom. I've included some performance options though that compensate for this very well. I've found that DLSS on 70% or even 60% screen resolution has a very minimal visual impact and makes it easy to maintain 60 fps on High on my mid-tier machine (RTX 2060 Super GPU, 3700x CPU). Additionally you can choose to toggle off groom hair shadows, which will also provide a nice FPS boost at the cost of the hair not receiving shadows. Furthermore I've had reports from users on high end machines being able to run the game at a stable 60 fps on Epic scalability with groom shadows enabled and 100% screen resolution. So all of my rambling here is probably irrelevant for high end users.

But rest assured, I'm very aware of the causes of performance pitfalls in this game, and it's not because of terrible coding practices or poor memory usage, the game thread isn't even close to being a bottleneck and CPU and memory profiling both show ideal results. I do put heavier code chunks in C++, and I use async loading as much as possible to keep the memory footprint as low as possible. The bottleneck is the GPU, and it's because I'm using features that are notoriously heavy, it's not because there's something fundamentally "wrong" with the way the game is coded or anything like that. 

Lastly, this project is about visual storytelling. The bulk of the content involves interactions with characters and narrative, as well as relatively simple minigames and jobs. It's supposed to be a relaxed vibe that you can do at your own pace. It's not CS:GO, it doesn't require split-second response times and it does not have shooting mechanics. So if you're disappointed that you're unable to run the game at 144fps, that's OK, you don't need to. There's no feature in the game that mandates having ultra high frames, and there's no content you can't complete if you have less than desirable frames. The point of this game is to be relaxed and perverted and enjoy the visuals. 

So hopefully this clears up some confusion if anybody is wondering why the game might not perform better on their machine, and rest assured I'm still actively researching ways to significantly improve performance without sacrificing too much quality.

Comments

Love the write up, development transparency (should) help with expectations since people don't know what goes on behind the scenes.

HongFire


More Creators