Search code examples
openglglsl

What kind of vector should I use to sample a cubemap?


I am wondering if someone can provide some clarification.

I have a cubemap with a side of 8192 pixels for both width and height.

I am using the following vector (see below dir_vector)to sample my cubemap,

#version 330 core

uniform vec3 hangle; // horizontal angular range and increment
uniform vec3 vangle; // vertical angular range and increment
out vec3 dir_vector;


void main(){
   for (float theta = vangle.x; theta < float(vangle.y); theta+= vangle.z){
       for (float psi = hangle.x;  psi <  float(hangle.y); psi+= hangle.z){
           float x = sin(radians(theta)) * sin(radians(psi));
           float z = cos(radians(theta)) * sin(radians(psi));
           float y = cos(radians(theta));
           dir_vector = vec3(x,y,z);
       }
   } 
}

It is clear that dir_vector is going to have a length of 1 and x,y,z are going to be within (-1.0,1.0).

Would the length of the vector need to be greater given the size of my cubemap?

I am also assuming that given the coordinates of the dir_vector opengl already knows which side of the cubemap to sample. is this assumption correct?


Solution

  • It is clear that dir_vector is going to have a length of 1 ...

    You have a mistake in your code. If you're looking to convert from spherical coordinates, the formula for y should then be:

    float y = cos(radians(psi));  // NOT theta
    

    Would the length of the vector need to be greater given the size of my cubemap?

    No. OpenGL samples from a cubemap based on the direction of the vector, ignoring the length.

    I am also assuming that given the coordinates of the dir_vector opengl already knows which side of the cubemap to sample. is this assumption correct?

    Yes. OpenGL determines the face of the cubemap based on the direction of the vector.

    Cubemap sampling

    The details of cubemap sampling are described in section "8.13 Cube Map Texture Selection" of the OpenGL spec.

    In short: The major axis is determined based on the coordinate of the largest magnitude. This is going to determine the cube-map face that's going to be sampled. The other two coordinates are divided by the major one, yielding values in the [-1, 1] range, then remapped to [0, 1] texture coordinates, which are then used to sample that face's texture like a regular 2d-texture.

    For example, given the input vector (10, 20, 100), the major axis is "positive z". OpenGL will calculate

    s = (10/100 + 1)/2 = 0.55
    t = (-20/100 + 1)/2 = 0.40
    

    and sample the GL_TEXTURE_CUBE_MAP_POSITIVE_Z face at coordinates (s, t). The conversion to an actual texel index will happen at this stage, taking the correct mipmap level into account.