Rendering a skybox on a fullscreen quad

Started by
6 comments, last by Promethium 14 years, 1 month ago
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?
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
Advertisement
Er..
Are you sure rendering to a full-screen quad instead of rendering as a simple box is a good idea (if at all possible)?
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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

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.
------------------------------Great Little War Game
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.
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.
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..
Wunderwerk Engine is an OpenGL-based, shader-driven, cross-platform game engine. It is targeted at aspiring game designers who have been kept from realizing their ideas due to lacking programming skills.

blog.wunderwerk-engine.com
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.



This topic is closed to new replies.

Advertisement