HomeGamesUpdatesPricingMethodology
Steam News10 July 20261mo ago

Pigeons at Devlog 7/10/26

Countering Projection Warping This little writeup is gonna be pretty technical, but I think it’s cool so too bad. Let’s say, hypothetically, New Atlas has a moon. We’ll call it a moonlet and toss it into orbit.

In this update2

Full notes

Full Mycopunk update

Read the full published notes in a cleaner layout. The original post stays linked below.

What changed

0 fixes2 additions6 changes0 removals
  • Gameplay
  • Performance
  • Maps
  • UI and audio
addedCountering Projection WarpingLet’s say, hypothetically, New Atlas has a moon. We’ll call it a moonlet and toss it into orbit. Just one problem - perspective cameras warp geometry as it approaches the edge of the screen, and an oblong moonlet looks dumb as hell.
changedCountering Projection WarpingWe could make the camera 2D, but then the mission select skybox (an inverted sphere) covers everything. So how do we get a perspective camera to render an object without warping it?
addedCountering Projection WarpingNew Atlas doesn’t have any visible warping because it’s right in the center of the camera’s view. Can we just render the moonlet in the center and then offset it back to its original position on the screen? As it turns out, yes we can!
changedCountering Projection WarpingThe planet’s vertex shader runs once for each vertex on the sphere and outputs that point’s position relative to the sphere’s center. We basically want to ‘swing’ the sphere over to the camera so let’s start by transforming the vertex and center into view space (in view space all positions are relative to the camera, which lies at (0, 0, 0)). Trigger warning for some shader code:
changedCountering Projection WarpingAt this point, the planet tries to render in the center of the camera’s view no matter where it’s placed, but we want to move it back toward its original position. We can calculate how much we have offset it and use that to offset it back to where it ‘should’ be in clip space.
changedCountering Projection WarpingAnd now it works! Right? That doesn’t look right. It turns out that since we use its object position to map textures onto the planet and we’ve applied an ungodly warp to the planet’s position, the texture mapping doesn’t work anymore. Not to worry, we just need to use our original object position to map the textures.

Mycopunk changes

addedLet’s say, hypothetically, New Atlas has a moon. We’ll call it a moonlet and toss it into orbit. Just one problem - perspective cameras warp geometry as it approaches the edge of the screen, and an oblong moonlet looks dumb as hell.
changedWe could make the camera 2D, but then the mission select skybox (an inverted sphere) covers everything. So how do we get a perspective camera to render an object without warping it?
addedNew Atlas doesn’t have any visible warping because it’s right in the center of the camera’s view. Can we just render the moonlet in the center and then offset it back to its original position on the screen? As it turns out, yes we can!
changedThe planet’s vertex shader runs once for each vertex on the sphere and outputs that point’s position relative to the sphere’s center. We basically want to ‘swing’ the sphere over to the camera so let’s start by transforming the vertex and center into view space (in view space all positions are relative to the camera, which lies at (0, 0, 0)). Trigger warning for some shader code:
changedAt this point, the planet tries to render in the center of the camera’s view no matter where it’s placed, but we want to move it back toward its original position. We can calculate how much we have offset it and use that to offset it back to where it ‘should’ be in clip space.

Countering Projection Warping

This little writeup is gonna be pretty technical, but I think it’s cool so too bad.

Let’s say, hypothetically, New Atlas has a moon. We’ll call it a moonlet and toss it into orbit. Just one problem - perspective cameras warp geometry as it approaches the edge of the screen, and an oblong moonlet looks dumb as hell.

We could make the camera 2D, but then the mission select skybox (an inverted sphere) covers everything. So how do we get a perspective camera to render an object without warping it?

New Atlas doesn’t have any visible warping because it’s right in the center of the camera’s view. Can we just render the moonlet in the center and then offset it back to its original position on the screen? As it turns out, yes we can!

The planet’s vertex shader runs once for each vertex on the sphere and outputs that point’s position relative to the sphere’s center. We basically want to ‘swing’ the sphere over to the camera so let’s start by transforming the vertex and center into view space (in view space all positions are relative to the camera, which lies at (0, 0, 0)). Trigger warning for some shader code:

// Transform object positions into view space float3 centerVS = mul(UNITY_MATRIX_MV, float4(0, 0, 0, 1)).xyz; float3 posVS = mul(UNITY_MATRIX_MV, float4(positionOS, 1)).xyz;

Then we calculate the angle needed to rotate the moonlet’s vertex from its current position to the camera’s origin. Sorry for the math.

// Direction from the camera to the sphere's center float3 from = normalize(centerVS); // Camera's forward direction float3 to = float3(0, 0, -1); // The cross product of 'from' and 'to' gives a vector that's perpendicular to both float3 axis = cross(from, to); float s = length(axis); // The dot product tells us close 'from' and 'to' are to pointing the same direction float c = dot(from, to);

Now we do some dark magic to calculate a matrix that will rotate the vertex over to the camera’s center. This is Rodrigues' rotation formula. I don’t know how it works. Matrices scare me.

float3x3 rot = float3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); if (s > 1e-5) { axis /= s; float3x3 k = float3x3( 0, -axis.z, axis.y, axis.z, 0, -axis.x, -axis.y, axis.x, 0); rot += s * k + (1 - c) * mul(k, k); } // Apply the rotation to our vertex position float3 posRotVS = mul(rot, posVS); // Transform it into clip space // Clip space is like half way between view space and screen space -_- float4 clip = mul(UNITY_MATRIX_P, float4(posRotVS, 1));

At this point, the planet tries to render in the center of the camera’s view no matter where it’s placed, but we want to move it back toward its original position. We can calculate how much we have offset it and use that to offset it back to where it ‘should’ be in clip space.

float4 clipCenterOrig = mul(UNITY_MATRIX_P, float4(centerVS, 1)); float4 clipCenterRot = mul(UNITY_MATRIX_P, float4(mul(rot, centerVS), 1)); float2 ndcOffset = clipCenterOrig.xy / clipCenterOrig.w - clipCenterRot.xy / clipCenterRot.w; clip.xy += ndcOffset * clip.w;

And now it works! Right? That doesn’t look right. It turns out that since we use its object position to map textures onto the planet and we’ve applied an ungodly warp to the planet’s position, the texture mapping doesn’t work anymore. Not to worry, we just need to use our original object position to map the textures.

Now it really works! It still has a tiny bit of warping, but that’s because we curve all the UI toward the edge of the screen after rendering.

And with that, X11-B renders correctly in the mission select screen. It’ll be open to visitors at 1.0.

-Liam

Explosions and Blood

There are a LOT of explosions in the game, which I feel like is a recurring problem when it comes to improving visibility in the game. These same issues also exist with the enemy death and limb destruction effects as well, which are very flashy and satisfying but can really get in the way — especially when using the Carver where they’ll be splashing in your face almost constantly.

I had previously solved this problem with first person versions of the explosions that won’t render in the center of your screen while you’re inside of them, but those are less performant, and more immersion breaking as it’s very obvious that they’re rendering weirdly for the purpose of a better view.

So what’s the solution?

Time manipulation :]

The method is rather straightforward: when an effect spawns too close to you, some parts of it will begin playing part of the way through, instead of playing from the very beginning. This is more prominent the closer an effect is to the camera so that (for example) at 4 meters away the effect will start 20% of the way through, and when it’s right on top of you it’ll start 40% of the way.

The end result looks like this:

For comparison, here’s what it used to look like (ft. Terry):

Pretty cool right? It’s a very small (and very easy) change that has a lot of payoff without looking super unnatural.

  • Noah

Source

Steam News / 10 July 2026

Open original post

Changelog.gg summarizes and formats this update. How we read updates.