Sign in to follow this  

Rendering a skybox on a fullscreen quad

This topic is 2839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I want to render a skybox on a fullscreen quad using a cube map. How can I compute the view vector for the cube map lookup? usually I'd do camPos-vertexPos (or wouldn't I?) but as the vertices do not correspond to an actual box I need to find the view vector in another way I guess. Any ideas?

Share this post


Link to post
Share on other sites
Quote:
Original post by szecs
Are you sure rendering to a full-screen quad instead of rendering as a simple box is a good idea (if at all possible)?
Certainly possible. You just treat it as a raycasting problem - construct a worldspace ray in the pixel shader, and use that to perform the lookup in the cubemap.

Share this post


Link to post
Share on other sites
I use a cubemap for convenience (so the same map can be used as reflection mapping on models etc). But I just draw a camera-aligned box instead and it just works by using vpos as the cube lookup.

Share this post


Link to post
Share on other sites
I did this a while ago, it's absolutely possible and you get a totally smooth sky without the artifacts from a skybox (seams and corners).

I think the way I did it was, in the vertex shader calculate the world space position of the vertex. Then, in the pixel shader, construct a ray from the camera world space position to the interpolated vertex world position and use that as a look-up in the cube map.

Share this post


Link to post
Share on other sites
Quote:
Original post by Vexator
usually I'd do camPos-vertexPos (or wouldn't I?) but as the vertices do not correspond to an actual box I need to find the view vector in another way I guess
Yeah, normalize(vertexPos-camPos) gives you a direction from the camera to sky-pixel, which is used as a tex-coord to sample a cubemap.
Using the information in your projection matrix, you can find this direction yourself.

For example
          -\tl
-/ \
-/ --\tr
/ --/ |
\--/ |
c N|fov | F
--\ |
--\ |
--\br
Near plane.
Far plane.
camera position.
top right corner of the far plane.
top left corner of the far plane.
bottom right corner of the far plane.
The slopes of the side planes are determined by the field of view angle.


We can imagine your fullscreen quad covering either the near or far plane (or any plane parallel to that).
Your quad only has 4 vertices, so we just need to find the direction from the camera to each of these 4 verts, which are: normalise(tl-c), normalise(tr-c), normalise(bl-c), normalise(br-c) (interpolating these 4 values gives you the correct direction anywhere on the quad).
If you calculate these 4 directions and use them as the normals for each of your vertices, you can use the normal as the tex-coord to sample the cubemap.

To take camera rotation into account (so you can look around at the skybox), these direction values must be transformed using the 3x3 rotational part of your camera's view matrix.

Share this post


Link to post
Share on other sites
Quote:
I think the way I did it was, in the vertex shader calculate the world space position of the vertex. Then, in the pixel shader, construct a ray from the camera world space position to the interpolated vertex world position and use that as a look-up in the cube map.


for a full screen quad in orthographic projection, the world space position of a vertex is simply the input vertex, i.e. gl_Vertex, isn't it?

VS:
varying vec3 v_ViewVector;

void main()
{
gl_Position = gl_ProjectionMatrix*gl_Vertex;

v_ViewVector = gl_Vertex.xyz;
}


FS:
varying vec3 v_ViewVector;

uniform samplerCube u_Texture0;
uniform vec3 u_CameraPosition;

void main()
{
gl_FragColor = textureCube( u_Texture0, v_ViewVector-u_CameraPosition );
}


but this gives weird results, so I guess I got you wrong..

Share this post


Link to post
Share on other sites
Quote:
Original post by Vexator
for a full screen quad in orthographic projection, the world space position of a vertex is simply the input vertex, i.e. gl_Vertex, isn't it?

No, that wont work. You need to take your vertices out of projection space (I always forget the proper name...) and back into world space. So you will need your view V matrix and perspective projection P matrix. Construct the inverse view-projection IVP = (V*P)^-1. Now you can transform your vertices by IVP to get them in world space: gl_Position = gl_ProjectionMatrix*gl_Vertex*IVP;

If you define your vertices in projection space, that is, where X and Y is in the [-1;1] range then you don't need the orthographic projection.



Share this post


Link to post
Share on other sites

This topic is 2839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this