Back to Blog

EF-Map Performance Mode: Two Free Fixes and One That Costs Frames

So I have spent a fair chunk of the last few weeks on interface work. It started as a tidy-up on EF-Map itself, and then it spread, because once the map had a consistent look the two companion tools stopped matching it. RootFit and CivilizationControl, the other two EVE Frontier tools I run, both got pulled into the same palette so that clicking between the three does not feel like changing websites. Most of that is written up already in Polishing EF-Map.

Then I ticked Performance Mode, and it looked terrible.

That is worth explaining, because I never normally see Performance Mode. I run a 4070 Super, so I sit in the default view, and if I am capturing a video or a screenshot I turn Cinematic Effects on instead. Performance Mode is something I know is there, know needs to be there, and know a decent number of people are genuinely using, either on a laptop or because they do not want a browser tab chewing their GPU while the game is running. It also switches itself on automatically for anyone on integrated graphics, which means a good number of those people never chose it and have no idea it is on.

With all the new Ember styling sitting around it, the map inside that mode did not look like part of the same product. Flat black behind the star field. Gate lines all the same weight no matter where they were. Stars that read as plain pixels.

The three things I wanted

The first was the background. In the default view there are three procedural dust shells behind the star field that give it warmth, and they follow whatever accent colour you have picked. In Performance Mode they are switched off and you get the clear colour underneath, which is pure black. So the ask was something much cheaper in their place. A gradient, basically, with a bit of colour depending on the theme, fading to black towards the top and bottom as if you are looking edge-on at the disc. Nothing clever. It just had to move with the camera so it feels like something is actually out there rather than a flat wall behind the stars.

The second was the stargate lines. In Performance Mode they all drew at the same weight, and in the default view they fade with distance. I spent a while tuning that fade originally and I have come to rely on it more than I expected. If you are sat looking at a stargate network you can tell which lines are near you and which are on the far side without touching the camera. Losing that in Performance Mode felt like losing information, not just polish.

The third one I could not describe properly, which made it the interesting one. There is some setting in the default view that makes stars pop even at a distance. In Performance Mode a far-off star is a dot. In the default view the same star reads as a star, and you can tell a hot blue one from a cool red one at a glance. For a tool whose whole job is conveying information about EVE Frontier systems, I thought that mattered more than it looked like it did.

Two of them cost nothing at all

The first surprise came quickly. The gate-line fade was not a feature Performance Mode was disabling to save work. It was the same shader running the same instructions in both modes, with one uniform set to zero.

The way that happened is fairly ordinary. Performance Mode zeroes a handful of display values, and two of them, the star depth brightness and depth desaturation, feed a single multiply in the fragment shader for both the stars and the gate lines. At zero, the near boost and the far dim both collapse to one, so everything renders at flat full weight. The GPU does exactly the same amount of work either way. There is no branch, no extra pass, no extra draw call. Zeroing it saved nothing and quietly cost the distance fade on the gate lines and a large part of the flatness in the star field, because near stars lost their brightness boost and far stars lost their dimming, so the whole field rendered at one level.

So that was not an optimisation at all. It was a mode reusing one setting to switch off six things at once, and two of those things were free. Restoring them is genuinely zero cost, not the hand-wavy kind of zero cost.

The background was nearly as cheap. Rather than a sky sphere, it ended up as a single full-screen quad drawn before everything else, where the gradient is worked out per pixel from the direction the camera is looking relative to the galactic plane. That means it tracks the camera for free, cannot clip, needs no texture, and is right at any zoom. One draw call and about twenty instructions per pixel with no texture reads. Compared to three shells of procedural noise it is not really worth measuring.

The background took longer than the code did

The code for that was quick. Getting it to look right took a lot longer, and I got it wrong twice.

The first version was too strong and too tightly banded. I settled on a broad soft wash at eight per cent intensity, which puts the brightest part of the frame somewhere around rgb(20, 14, 4) for the Ember theme. That is genuinely faint. I checked it on a bright monitor and a dark one, because the whole point is that it lifts the black without being obvious, and it has to survive someone switching to the blue or green accent without turning garish.

Then bloom got involved and blew it out completely. Turning bloom on in Performance Mode turned the whole background into a solid mustard wash. That one was a colour space mistake. The gradient was written as a finished display colour, which is only correct when it goes straight to the canvas, and with bloom on the frame goes through a post-processing chain that treated the value as linear and re-encoded it. About four times too bright.

The fix for that then broke it the other way, which is the bit I would have missed if I had not had both previews open in two tabs. The background got noticeably darker, to the point where on my dark monitor it was basically black again. Two separate errors underneath it. The inverse curve being used was not actually the inverse of the sRGB curve, so an authored value of 0.08 was landing at 0.049, and worse the darker the value got. And tone mapping was being applied to it, which subtracts a black point equal to the darkest channel and had been crushing the blue channel to zero, so the thing had lost its warmth as well as its brightness. Measured on the same patch of empty sky it had gone from rgb(4.5, 1.9, 0.0) to rgb(12.3, 8.4, 2.5) once both were sorted.

I am glad I noticed. It is exactly the kind of regression that would have shipped, because it still looked like a faint tint if you had nothing to compare it against.

The third one was bloom, and bloom is not free

The star pop turned out to be bloom, and only bloom. I checked that by holding everything else steady and toggling one thing at a time, which is the only way I would trust an answer like that.

Before landing on bloom I went down a dead end with the glow layer, which seemed like the obvious cheap option. It draws a soft halo sprite around bright stars, so on paper it is the effect I wanted. It does nothing at range though, and the reason is that its distance window closes at about 2000 units while the overview camera sits more than 5000 out, so its opacity is already zero before it reaches anything you can see. That is why turning the glow slider up did nothing until I flew right in close.

I did try widening that window to 40,000 units and pushing the slider up. Still nothing visible, because the layer's brightness is scaled down hard for additive blending, and a slider at 0.12 comes out at 0.0016 by the time it reaches the shader. You would need roughly a hundred times what the slider allows, and the same layer serves close-up views so it would blow those out. No cheap substitute hiding in there.

Bloom works at range for a simple reason. It is a screen-space operation with no concept of distance, so it takes a single bright pixel and spreads its energy into a small halo. That is what turns a one-pixel dot into something that reads as a star, and it is why you can tell temperature apart at a distance in the default view.

Then I measured what it costs. On the 4070 Super at 1080p, with the resolution Performance Mode already runs at, going from bloom off to bloom on takes the frame from about 0.29 milliseconds to about one millisecond. So roughly 0.7 of a millisecond, every frame, forever.

The interesting part is where that goes. Almost all of it is the CPU cost of submitting the extra passes rather than the GPU cost of running them. It also barely moved when I went up to 1440p, so it behaves like a fixed overhead rather than something that scales with your screen. That cuts both ways. It will not get worse on a big monitor, but it is not going to get cheaper on a weak laptop either, and it might be worse there.

Strength turned out to be free, which changed the decision

I had assumed a small amount of bloom would cost less than a lot of it. It does not. At two per cent it measured 1.01 milliseconds and at twenty five per cent it measured 0.97, which is the same number twice with noise on top.

That is because the strength value is only used as a multiplier right at the end of the chain. Every blur level still runs, the bright pass still runs, every render target still exists. There is a cliff at zero and then a flat line.

So the choice is not how much bloom, it is bloom or no bloom, and the amount is purely a look decision. That is quite freeing. Pick whatever looks right and it costs the same.

Who gets it switched on

That left the awkward part, which is a real effect that costs real frames, and a user base I cannot see.

Bloom was already in the settings, but it sat in the starfield section among four other sliders that control different aspects of it, and in Performance Mode the slider did nothing at all because the mode ignored it outright. Someone in Performance Mode with a bit of headroom had no way to get the effect even if their machine could afford it.

So it is now a plain checkbox sitting directly under the Performance Mode toggle, where somebody hunting down a frame rate problem will actually find it. The explanation lives in the help panel rather than beside the checkbox, because two toggles and three lines is about all that card should be.

The defaults are where I spent most of the thinking. Anyone already using Performance Mode when this goes out gets the two free effects and does not get bloom. Their frame rate does not change, which felt like the only honest option, since they never asked for it. Anyone put into Performance Mode automatically because of their graphics does not get it either, for the same reason but more so. Those are the machines the mode exists for.

But if you are on a desktop and you tick Performance Mode yourself, maybe because you want to keep some GPU back for the game, bloom stays on and the map still looks like the map. If it turns out you cannot afford it, the checkbox is right there.

I think that is the right split, although I will admit the thing I am least sure about is the numbers. Every measurement here came off a 4070 Super, and the people this mode is built for are on hardware I do not own and cannot test. If the map feels slower after this, unticking star bloom is the first thing worth trying, and that only affects you if you turned Performance Mode on yourself.

The wider point, and the reason I thought this was worth writing up at all, is that Performance Mode had quietly become the part of EVE Frontier's map that looked a year out of date, and it looked that way to people who never opted into it. Two of the three things that bothered me were free and had been switched off by accident. The third was genuinely expensive and needed a decision about who pays for it rather than a clever trick. I would not have found any of it if I had not gone and sat in a mode I never use.

Anyway, it is all live now. If something looks off in Performance Mode, or the background is too much or not enough on your screen, let me know and I will have a look.

Related Posts

Polishing EF-Map: Turning 12 Months of UI Into One System is the interface work that led directly to this, and the reason Performance Mode suddenly looked out of place. Starfield Depth Effects: Adding Subtle Immersion to a 3D Universe is where the distance fade on the stars and gate lines came from originally. Giving Our EVE Frontier Starfield HDR Stars with Claude Fable 5 covers the bloom and HDR work that makes the star temperatures readable in the first place. Does This Look AI-Generated? Rebuilding EF-Map's Visual Identity with Claude Fable 5 is where the Ember theme and the accent colours came from.
performance mode webgl optimization bloom post-processing three.js colour space integrated gpu accessibility defaults eve frontier