Portal-like mirror

Hi @CarlBateman, thatā€™s quite interesting! I havenā€™t looked at your project, posting this portal engine example here in case you havenā€™t seen it:

https://playcanvas.github.io/#/graphics/portal

1 Like

Thanks, Iā€™ve seen this but Iā€™m not sure that it helps.

I think it would need an entirely different approach to the one Iā€™m trying at the mo. :thinking:

1 Like

I think the issue (at least for now) is that the camera sees and renders this

But should only render what it sees within the black area.

1 Like

Maybe using a stencil buffer could help here?

https://developer.playcanvas.com/en/tutorials/stencil-buffer---3d-magic-card/

1 Like

Having looked at that project and a few others, from what I can tell, the stencil masks off areas, discarding/not rendering them, resulting in something like this (please correct me if Iā€™m wrong).


Whereas, I need the render to be cropped/triimed/resized, giving something like this.


Also, I canā€™t see how it would work with multiple cameras/layers. :cry:

The other thing you could do is change the offset and tiling properties on the material based on size of rge mirror on the screen?

Not sure how well that works when looking at it at an angle :thinking: maybe the UVs can be manipulated instead?

Edit: the more I think about it, changing the UVs would make more sense with the render texture for the reflection being the same aspect ratio as the browser window.

This isnā€™t a direct answer to your question, but there is this in-depth talk by Valve developers discussing how they overcame all sorts of problems while developing Portal. Itā€™s a long talk but they cover some fascinating situations in detail that we donā€™t typically encounter in 3D game dev.

1 Like

Iā€™ll check that out.

Yeesh! Despite some progress, I must admit this is doing in my noodle somewhat. :crazy_face:

So, Iā€™ve tried to make things even simpler to visualise by trying to make a window using the same principles Which results in this.


(https://playcanvas.com/project/873297/overview/portallike-window).

It looks like the next step should be getting that inner blue area to render to the outer green area.
Most likely a scaling and UV issue, but I really have no idea where to even start. :scream: :question: :thinking:

A brief diversion for a bit of research.

I think the answer lies with a custom projection matrix and accompanying asymmetric frustum.
(https://forum.playcanvas.com/t/issue-with-non-square-aspect-ratio-and-resizing/10317/10)

Now I just need to derive the matrix and the frustum. Easy. :scream:

1 Like

By the way, if youā€™re trying to set up mirror rendering, you donā€™t need off-center camera as discussed in a separate thread. You just need to reflect the camera position / facing by the mirror plane. The concept here is that the camera will not be positioned at the surface of the mirror, as youā€™re trying to do ā€¦ but behind the mirror (same distance as the main camera is in front it it). Iā€™m sure there are some online tutorials with detail explanations for this as well.

Unfortunately that wonā€™t work. As can be see from the images above, the area seen by the camera is too big (and is offset, but that may not be clear from the images). Iā€™m trying to reduce the area seen by the camera to the ā€œarea of interestā€ as indicated by the blue frame.

Ideally, this would be done by setting glViewport appropriately (I think) but (1) it isnā€™t exposed (2) the PlayCanvas viewport is normalised (3) Iā€™m not sure the PlayCanvas viewport is the same as glViewport.

Also, see below.

White is the main camera viewport/frustum.
Green is the (much smaller) window cameraā€™s ā€œarea of interestā€ desired viewport/frustum.

Well, Iā€™ve made significant progress with the window (thanks in no small part to @mvaligurskyā€™s help in a different thread).

Itā€™s about 90%(?) done. Check it out (https://playcanvas.com/project/873297/overview/portallike-window).
It sort of works, but the scale and offset are off by a small factor, and I canā€™t figure out where Iā€™ve gone wrong.

So, once again, Iā€™m asking for any suggestions as what may be wrong and how to fix it.

TIA

1 Like

After quite a bit of research, Iā€™d just about convinced myself that my approach was flawed due differences in the view render and the target texture being asymmetric and different shapes.

But after tweaking values I was able to get the result below, which looks pretty darn good.

Thereā€™s seems to be some non-linear factor or error Iā€™m overlooking, but I have no idea what.

Help me, Obi Wan Kenobi! Youā€™re my only hope!

2 Likes

Iā€™ve made significant progress with the windowā€¦ untilā€¦ the player gets close and then it breaks :crazy_face:

Portal window video

A fudge factor is calculated in code, but itā€™s pretty much random numbers.

let fudge = dist * 1.5 + 0.625;
fudge = 1 + tFOV / fudge;
tFOV *= (180 / Math.PI);

I think I need to take a breath and try to understand whatā€™s going on :thinking: :scream:

1 Like

Hi @CarlBateman! Sorry, I didnā€™t follow this topic, but could it be that the player is behind the camera at that point? If thatā€™s the case you need to flip some values.

@Albertos Not really, the camera is attached to the player so can never be behind them.

Whoops! Another major issue.

When the player gets too close to the ā€œwindowā€ surface, the rendered image becomes blurry (I know why, but I donā€™t want to come up with a fix until the other issues are sorted).

This looks fun!

For anyone interestedā€¦ Iā€™ve hacked a few fudge factors together because the scaling is not well-behaved. And it seems to work pretty well (the different coloured sky is deliberate)ā€¦

Untilā€¦

When the players is very close to the window, the scaling breaks down quite catastrophically.

I canā€™t see a workable fix for this. Cranking up the resolution on the render target ā€œworksā€ but hobbles performance. So, ultimately a dead-end. At least, for now.

Iā€™ll use this technique for a mirror and a portal but only for the sake of completion, and out of curiosity.

A pity really, this method looked quite promising early on but let me down in the end. :frowning_face: