SPECIALIZATION

I am partly interested in both rendering and gameplay, to be able to challenge myself within these two categories I decided to try to replicate the portals from Portal 2 together with the perspective scaling from Superliminal and combine these together.

I am very happy with the result considering the time that was spent on it. You can view the result in the video below!

THE RESULT

PORTALS RECREATION

THE GOAL

I love the portal games and I wanted to re-create the seemless portal feature from it.

PROBLEMS ENCOUNTERED

ACHIEVING CORRECT PROJECTION

The result being displayed in the GIF is an already perspective divided result, however, it was “flat” because it was simply a flat texture.

Another step was need to properly project the result onto the resulting target quad.

To achieve that I thought about my previous knowledge from implementing deferred decals which was done by calculating the UV screen space coordinates.

I was able to solve this issue the same way.

OBJECT WERE DRAWN IN FRONT OF PORTAL

To achieve the  effect I am moving the target portal camera and rendering with that. When objects are in between the camera and the portal, it renders the objects.

My initial attempt to solve was to use 2 different projection matrices for the camera. One for culling with near plane further forward to the portal with same rotation as portal, another one for rendering. This did not work properly because it culled stuff that was in the render view.

Second attempt was done using a beautiful thing called “oblique matrix” which is making the near plane be straight at an angle.

PORTAL RENDERS ITS OWN PORTAL TEXTURE

The initial solution was to simply cull the portals for the portal cameras. Now they do not render them. It fixed the issue, however, looks weird and I want to be able to see portals through portals recursively.

The final solution was to control the rendering order of the portal cameras myself and simply disabling its own portal texture when drawing the camera.

RECURSIVE PORTALS WAS NOT WORKING FOR FREE

This was fun to do, I solved it by drawing the deepest portal (painters algorithm) and then backtracking and everytime calculate the proper position and rotation for each portal.

There are performance issues depending on how deep the recursion is that I ignore at the moment.

SEAM WHEN CAMERA MOVES

When moving camera, the portal shows a seam which looks like it has 1 frame delay and using the previous frames result.

That was partly true and was because I originally calculated the destination portal camera transform then drawing the current portal and vice versa. Meaning I caused the 1 frame delay.

This was fixed by actually calculating the correct camera transform for the one I was going to render.

1 FRAME OF EMPTINESS

When moving through a portal, when teleporting the player and the camera to the destination portal, 1 frame of empty world would appear.

The solution was to simply change script order execution to ensure that the rendering of the portals occur after actually teleporting the player.

UNSOLVED ISSUES

If I was able to spend more time, there are a couple of problems I would like to solve.

  • When having multiple portals, performance drops quite a lot and proper culling of the portals would be very beneficial.
  • It is not 100% seemless when going through a portal, there is a couple of units deadspace when you are in the middle of the portal texture quad. Meaning, when going through, the camera is not allowed to be too near the portal texture to avoid clipping.
  • Unlimited recursion is not handled at the moment, the deepest portal recursion is not handled properly and is glitchy looking.

HINDSIGHT THOUGHTS

If I had more time, I would like to add another feature which involved picking up and placing objects within a portal. Would be very cool.

I did not anticipate this many issues needing to be solved because they kept appearing one after the other. Another thing, I initially thought doing it in Unity would be easier than doing it in our own Engine. But in hindsight, I am not sure if that’s really true. Doing it in our own engine, I would have much more control over the rendering part.

SUPERLIMINAL RECREATION

THE GOAL

The goal for this is to re-create the perspective scaling feature from Superliminal as seen in the below GIF.

THE SCALING MATH

Something I initially expected to be more difficult turned out to be quite easy to understand.

Using the Intercept Theorem or ratio of similar triangles we can get the formula.

Which says that an object of size s1 with the distance from camera d1, with another distance of d2, the size s2 is given using the following formula.

 

PROBLEMS ENCOUNTERED

FINAL OBJECT POSITION INTERSECTED OBJECTS

First iteration had a big issue where I was unable to find the correct position  for the carried object.

SweepTest was not scaled up. Unity does not support.

Tried SweepTest for each unity forward while scaling and moving the object. Did not work because SweepTest works on the Rigidbody which seems to not be able to change position during a frame.

Bad because poor performance on large distances.

Next was Raycasting lines from the vertices. Gives me perspective scaling collision checks for free.

Had to avoid collision by offsetting the object and then doing another perspective pass onto it with the newly offsettet position.

THE FINAL POSITION INTERSECTED OTHER GEOMETRY

After figuring out the resulting object size and distance, very often the object was intersecting other geometry at target position.

This issue was solved by offsetting the resulting position by the intersecting vertex and then again re-calculating the size and distance.