不懂learnopengl.com中Diffuse-irradiance教程中的captureViews

Do not understand captureViews in Diffuse-irradiance tutorial in learnopengl.com

我正在 https://learnopengl.com/PBR/IBL/Diffuse-irradiance 学习 IBL。

本教程通过创建 6 个视图将等距柱状图转换为立方体贴图。

并且视图是以下代码:

glm::mat4 captureViews[] = 
{
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec3(0.0f,  0.0f,  1.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec3(0.0f,  0.0f, -1.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec3(0.0f, -1.0f,  0.0f)),
   glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec3(0.0f, -1.0f,  0.0f))
};

我不明白glm::lookAt的第三个参数。

glm::lookAt的第三个参数是up向量。我认为 captureViews 应该是:

// zero is    [0, 0, 0]
// right is   [1, 0, 0]
// left is    [-1, 0, 0]
// up is      [0, 1, 0]
// down is    [0, -1, 0]
// back is    [0, 0, 1]
// forward is [0, 0, -1]
glm::mat4 captureViews[] = 
{
   glm::lookAt(zero, right, up),
   glm::lookAt(zero, left, up),
   glm::lookAt(zero, up, back),
   glm::lookAt(zero, down, forward),
   glm::lookAt(zero, back, up),
   glm::lookAt(zero, forward, up)
};

但我完全错了。我不明白教程 up 向量中的魔法。

谁能帮我解释一下?

使用立方体贴图纹理时,必须将 3 维方向向量转换为相对于贴图一侧的 2 维纹理坐标。

此转换规范的相关部分是 OpenGL 4.6 API Core Profile Specification, 8.13 Cube Map Texture Selection,第 253 页:

When a cube map texture is sampled, the (s t r) texture coordinates are treated as a direction vector (rx ry rz) emanating from the center of a cube. The q coordinate is ignored. At texture application time, the interpolated per-fragment direction vector selects one of the cube map face’s two-dimensional images based on the largest magnitude coordinate direction (the major axis direction). If two or more coordinates have the identical magnitude, the implementation may define the rule to disambiguate this situation. The rule must be deterministic and depend only on (rx ry rz). The target column in table 8.19 explains how the major axis direction maps to the two-dimensional image of a particular cube map target. Using the sc, tc, and ma determined by the major axis direction as specified in table 8.19, an updated (s t) is calculated as follows:

s = 1/2 * (s_c / |m_a| + 1)
t = 1/2 * (t_c / |m_a| + 1)


Major Axis Direction|        Target             |sc |tc |ma |
--------------------+---------------------------+---+---+---+
       +rx          |TEXTURE_CUBE_MAP_POSITIVE_X|−rz|−ry| rx|
       −rx          |TEXTURE_CUBE_MAP_NEGATIVE_X| rz|−ry| rx|
       +ry          |TEXTURE_CUBE_MAP_POSITIVE_Y| rx| rz| ry|
       −ry          |TEXTURE_CUBE_MAP_NEGATIVE_Y| rx|−rz| ry|
       +rz          |TEXTURE_CUBE_MAP_POSITIVE_Z| rx|−ry| rz|
       −rz          |TEXTURE_CUBE_MAP_NEGATIVE_Z|−rx|−ry| rz|
--------------------+---------------------------+---+---+---+

sc cooresponds the u coordiante and tc to the v cooridnate.所以 tc 必须在视图方向 space 向上矢量


看table的第一行:

+rx | TEXTURE_CUBE_MAP_POSITIVE_X | −rz | −ry | rx

这意味着,对于立方体贴图的X+侧(右侧),切线和副法线对应的方向是

sc = (0, 0, -1)
tc = (0, -1, 0)

这与 table glm::mat4 captureViews[] 的第一行完全匹配:

glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))

因为主要方向是由视线给出的,它是从眼睛位置到目标的方向 (los = target - eye) 等等 (1, 0, 0)。
向上向量(或 ts)是 (0, -1, 0).
sc由视线与上向量(0,0,-1)的叉积给出。