5
\$\begingroup\$

I'm trying to follow This tutorial for a portal mask shader. It's an awesome effect but it comes with a couple of caveats. The shader as he designs it can only exist in a bubble, as:

  1. The portal is visible through other objects (this I solved by finagling the queue order): Spherical portal visible through pillar

  2. The illusion the portal creates of another space within is broken as soon as you enter: Portal vanishes as player steps into it

As loading can't be perfectly instantaneous, this means when a player enters the portal, there will be a brief moment in which they are right back outside it, which I feel ruins immersion.

In order to compensate for this, I figured I would try to extrude the edges of the mask geometry, which works for the inside of the portal..

View inside mouth of portal

..but introduces the new problem of the front faces of the inside of the object being visible:

Portal interior visible from behind/beside

So what I'm hoping to achieve is a shader which:

  • Occludes the PortalMask shader/object from the outside only
  • Does not occlude other environment objects
  • Is not itself visible

Am I asking the impossible?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ "As loading can't be perfectly instantaneous" the fix here is to have the load already completed, so when the player moves through the portal you just teleport them to the already-loaded alt scene, rather than starting the loading a frame too late. Transition effects can help too. Also, have you considered toggling between two portal visuals (a flat one used by default, and the extruded one used only when the camera enters the portal volume through its aperture)? This is likely to be easier to manage and more robust than trying to selectively clip the extruded one from certain viewpoints. \$\endgroup\$
    – DMGregory
    Commented Jul 2, 2023 at 17:03
  • 2
    \$\begingroup\$ Also, +1 for an extremely well-illustrated question. 😁 \$\endgroup\$
    – DMGregory
    Commented Jul 2, 2023 at 17:59
  • \$\begingroup\$ You have a point; I was actually thinking it might be far more simple to just either disable the geometry via script until the player collides with the object like you said or freeze the player character at the collider so they can't ever see anything more than the inside of the portal. I should have mentioned this is for Quest, though, so pre-loading a scene would be too much a burden on the hardware. Thank you for the suggestions! I'll test these out~ \$\endgroup\$
    – ninthtale
    Commented Jul 3, 2023 at 15:01
  • \$\begingroup\$ The scene you pre-load does not have to be the whole destination scene. It can be a transition corridor just big enough to hold the player while you unload the old scene and bring in the new. \$\endgroup\$
    – DMGregory
    Commented Jul 3, 2023 at 15:24

1 Answer 1

1
\$\begingroup\$

A simple trick for this is to add a second shader pass, or second material that renders before the main one.

Switch the culling mode to cull front faces and draw back faces instead. Write to the depth buffer but leave the colour buffer unchanged.

This puts an invisible occluder in front of the front faces when viewed from the side, so they don't draw through it.

The downside with this is that it will also include any transparent effects drawn after the portal, like particles. It also only works from outside the portal volume. Inside, you'll see the front faces unoccluded, even if you walked in from the side rather than through the aperture.

I think a better solution is to keep the portal flat. Make a corridor out in empty space with your portal interior effect. As soon as the camera position crosses the portal, teleport the player into the corresponding position in the corridor, so that the player doesn't see any visible cut. (You can have an imposter of the room they just left in case they turn around, obscured by magical portal effects to disguise artifacts)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .