Monday, May 11, 2015

opengl - With what projection matrix should I render a portal to a texture?


I'm using OpenGL. I have problem with my engine's portal implementation. To create the first portal I do:



  1. create a virtual camera with the position of the second portal and the correct orientation

  2. render whole scene from virtual camera to the texture using FBO

  3. render the first portal using the texture created before.


The problem: The virtual camera is rendering to the texture with the main projection view, so when I use this texture to render the first portal, everything is rescaled. The virtual camera should only render some part of the view to prevent scaling.


The problem could perhaps be solved by changing the virtual camera's projection matrix, but I don't know how to calculate such a matrix.


Here's how it looks:



Portals, currently


This picture shows one portal (the texture is a little bit deformed on bottom and top, but that's not important now) and some other objects. The second portal is behind the camera, and the camera is in the middle between the two portals.


We can clearly see that the portal texture is rescaled down to the portal size. As I said before, I think the virtual camera should have another projection matrix, but how do I calculate it? Or is there a better way?



Answer



Disclaimer: I haven't tried making a portal system, but I think this should work.


From your description I gather that you are rendering the "portal camera" to a buffer then applying this buffer as the portal texture. This is what I would do for a security camera, but for a portal I think we can do something else. If you stick with this method though, then changing the projection matrix would probably work.


However I think you should be doing is;



  • Draw the scene as normal (Builds a depth buffer)

  • draw the portal geometry to a stencil buffer.


    • Keep depth testing on so you don't draw the portal stencil over occluding geometry.



  • Flush the depth buffer

  • Render using the portal camera (which has the same projection matrix) and the stencil buffer such that you only draw to the portal area.


For more info on how to do this please see here.


PS: If sticking with the first method, then I don't know how to work out the projection matrix but you can fix this by simply changing the UV coordinates for the portal geometry. The UV coordinates can be calculated by projecting the portal vertices to the screen (multiply each vertex by world * view *projection) then dividing the x and y by the screen width and height (you may not need that last division, I can't currently remember if you get screen coordinates after multiplying by the projection or just some screen coordinate expressed from 0-1).


PS2: If I was to guess at calculating the projection matrix then;



For the portal camera projection matrix I think the FoV would be half the angle between vectors Vert1-CamPos & Vert2-CamPos (where Vert1 and Vert2 are either the top or bottom 2 vertices of the portal) and the aspect ratio would be the ratio of the width and length of the portal geometry. When calculating the angle you may need to 0 the y component of each vertex and the camera position and keep in mind this would only work for a rectangular, y-axis aligned portal.


If doing the whole projection matrix yourself, then the frustum is created by the 4 vectors defined by going from each vertex of the portal to the camera position.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...