In unity3D you frequently have quantities given as `float4`

, homogeneous coordinate system, however when working with 2D games it's useful to convert that to `float2`

and back:

```
float2 to_float2(float4 i) {
return i.xy / i.w;
}
float4 to_float4(float2 i, float4 rest) {
return float4(
i.xy * rest.w,
rest.zw
);
}
```

This converts nicely back and forth, `rest`

variable is used to restore original z and w values.

On the other hand, we can just directly cast `float3`

to `float2`

without having to worry about `w`

coordinate (still in some cases you might care about `z`

coordinate).

Let's say that we export players position into global shader properties:

```
public void LateUpdate() {
Shader.SetGlobalVector(
"_playerOffset",
playerTransform.position
);
}
```

In order to produce following effect (background is darkened dynamically around the player character):

We can use following vertex and fragment shader in unity3d:

```
// Global property
float3 _playerOffset;
struct v2f {
float4 pos : POSITION;
float green : COLOR;
};
v2f vert(appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float4 v_pos = mul(UNITY_MATRIX_MV, v.vertex);
float dist = length(float2(_playerOffset) - to_float2(v_pos));
o.green = (dist <= 1) ? dist/2 : 0.5;
return o;
}
float4 frag(v2f i) : COLOR {
return float4(0.2, i.green + 0.2, 0.2, 1);
}
```

Assume that speed of light is low, and think about this. When vertex has constant velocity and you want to render it on the screen, that vertex should not be rendered in it's original location. Given that vertex is some distance away from the player, it takes time for the light to reach the player.

We can compute quantities like:

$$ \vec{v} = \text{vertex velocity} $$

I should note that $\vec{v}$ has same direction as $\vec{c}$.

$$ \vec{a} = \text{from player to proper vertex location} $$

$$ \beta = \arccos{\frac{\vec{v}\cdot\vec{a}}{\left|\vec{v}\right|\cdot\left|\vec{a}\right|}} $$

If we think about the time it takes light to reach **player** from **visible** position. In that same time, vertex has moved from **visible** position to **proper** position. Thus:

$$ \frac{\left|\vec{c}\right|}{\left|\vec{b}\right|} = \frac{\text{vertex velocity}}{\text{speed of light}} $$

This problem falls under `SSA`

solution of triangles, you can read about it on a wiki page: Solution of triangles.

$$ \sin{\gamma} = \frac{\left|\vec{c}\right|}{\left|\vec{b}\right|}\sin{\beta} $$

$$ \alpha = 180^0 - \beta - \gamma $$

And finally length of $\vec{c}$ is given by $$ \left|\vec{c}\right| = \left|\vec{a}\right| \frac{\sin{\gamma}}{\sin{\alpha}} $$

Putting it all together, it looks like this:

I should note that special relativity effects are not included in any shape or form.

You can see the final demo in here: UniDemo1.html (Jump with space on keyboard).

If you jump off the cliff, visible object will move far back to the left. We need a way to keep history of objects in memory, that way we can switch between two (or more) movement velocities from back in time.

Also, some special relativity would be a nice touch.