Skybox

This example shows how to create a skybox using a cubemap texture.

Project files

This example shows how to create a skybox. A skybox is a technique that makes the scene look bigger and more impressive by wrapping the viewer with a texture that goes around the camera 360 degrees.

An in-depth explanation of skybox rendering can be found in Tutorial 25 of OGL Dev.

One of the key components of a skybox is the cubemap texture. A cubemap is a texture that contains 6 individual 2D textures that each form one side of a cube: a textured cube.

The cubemap is projected on a sphere or a cube positioned in such a way that the camera and other objects are placed inside the cubemap:

Skybox texture by Jockum Skoglund aka hipshot. Free to use.

Scripts

skybox.fp

#version 140

in mediump vec3 var_texcoord0;

uniform samplerCube cubemap;

void main()
{
	gl_FragColor = texture(cubemap, var_texcoord0);
}

skybox.vp

#version 140

uniform vs_uniforms
{
	uniform mediump mat4 view_proj;
	uniform mediump mat4 world;
};

in highp vec3 position;

out mediump vec3 var_texcoord0;

void main()
{
	/*
	 * Transform the position vector using the world view projection matrix
	 * and override the Z component with the W component. After the vertex
	 * shader is complete the rasterizer takes gl_Position vector and performs
	 * perspective divide (division by W) in order to complete the projection.
	 * When we set Z to W we guarantee that the final Z value of the position
	 * will be 1.0. This Z value is always mapped to the far Z. This means that
	 * the skybox will always fail the depth test against the other models in
	 * the scene. That way the skybox will only take up the background left
	 * between the models and everything else will be infront of it.
	 */
	mat4 wvp = world * view_proj;
	vec4 wvp_pos = wvp * vec4(position, 1.0);
	gl_Position = wvp_pos.xyww;

	/*
	 * Use the original position in object space as the 3D texture coordinate.
	 * This makes sense because the way sampling from the cubemap works is by
	 * shooting a vector from the origin through a point in the box or sphere.
	 * So the position of the point actually becomes the texture coordinate.
	 * The vertex shader passes the object space coordinate of each vertex as
	 * the texture coordinate and it gets interpolated by the rasterizer for
	 * each pixel. This gives us the position of the pixel which we can use for
	 * sampling.
	 */
	var_texcoord0 = position;
}