gpt4 book ai didi

c++ - OpenGL 立方体贴图面顺序和采样问题

转载 作者:行者123 更新时间:2023-11-30 04:49:05 24 4
gpt4 key购买 nike

我有一个基于 SDL2 和 OpenGL(3.3 核心配置文件)的渲染器,它为我提供了关于转换和纹理 (2D) 的预期结果。

但是,当我尝试使用从 these textures 创建的立方体贴图来显示天空盒时(虽然我也尝试过其他的),这个过程中有两个步骤是我遇到的其他教程或示例似乎都不需要做的,我无法解释:

1,上传时必须交换顶面/底面,即:上面的面上传为GL_TEXTURE_CUBEMAP_NEGATIVE_Y,下面的面为GL_TEXTURE_CUBEMAP_POSITIVE_Y;2,采样立方体贴图时,我必须沿 y 反转顶点位置,但沿 z ;

如果没有这个,我会得到以下结果:

enter image description here

(注意左下远顶点被缩放了 0.8 以澄清我的坐标系是正确的)

图像文件命名正确。

立方体是我正在执行的唯一绘图。

如果我删除任何边的[索引],我会得到预期的结果(即那里没有交换/镜像)。

我的集成 GPU 和专用 GPU 似乎得到了相同的结果。

我的 OpenGL 常量,来自 glLoadGen ( originally ) 生成的 header :

#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519

纹理上传代码(与LearnOpenGL's tutorial 大致相同):

GLuint name;
glGenTextures(1, &name);
glBindTexture(GL_TEXTURE_CUBE_MAP, name);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

GLint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
for (uint8_t i = 0; i < 6; ++i)
{
glTexImage2D(target + i, 0, GL_RGB8, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, pixelData[i]));
}

顶点着色器:

#version 330

precision mediump float;
uniform mat4 uModelViewProjection;
in vec3 aPosition;
out vec3 vTexCoord;

void main()
{
vec4 position = uModelViewProjection * vec4(aPosition, 1.f);
gl_Position = position.xyww;

vTexCoord = aPosition;
}

片段着色器:

#version 330

precision mediump float;
uniform samplerCube uTexture0;
in vec3 vTexCoord;
out vec4 FragColor;

void main()
{
FragColor = texture(uTexture0, vTexCoord);
// using textureCube() yields a compile error asking for #extension GL_NV_shadow_samplers_cube : enable, but even with that, the issue perists.
}

网格设置(半伪代码):

//    4----5
// /| /|
// 6----7 |
// | | | |
// | 0--|-1
// |/ |/
// 2----3
VertexType vertices[8] = {
Vector3(-1.f, -1.f, -1.f) * .8f, // debug coordinate system
Vector3(1.f, -1.f, -1.f),

Vector3(-1.f, -1.f, 1.f),
Vector3(1.f, -1.f, 1.f),

Vector3(-1.f, 1.f, -1.f),
Vector3(1.f, 1.f, -1.f),

Vector3(-1.f, 1.f, 1.f),
Vector3(1.f, 1.f, 1.f),
};

uint16_t indices[] = {
4, 0, 5,
0, 1, 5,

6, 2, 4,
2, 0, 4,

7, 3, 6,
3, 2, 6,

5, 1, 7,
1, 3, 7,

0, 2, 1,
2, 3, 1,

5, 7, 4,
7, 6, 4,
};

// create buffers & upload data

渲染(伪代码):

// -clear color & depth buffers;
// -set the model transform to a translation of -10 units along z;
// view transform is identity; projection is perspective with .25
// radians vertical FOV, zNear of .1, zFar of 100.; viewport is full screen
// -set shader program;
// -bind texture (same name, same target as upon uploading);
// -enable backface culling only (no depth test / write);
// -draw the cube
// -glFlush() and swap buffers;

究竟是什么导致了上述两个问题?

最佳答案

问题是由 .str 纹理坐标到立方体贴图的映射引起的:

OpenGL 4.6 API Core Profile Specification, 8.13 Cube Map Texture Selection, page 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 (sc / |m_a| + 1)

t = 1/2 (tc / |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|
--------------------+---------------------------+---+---+---+

Table 8.19: Selection of cube map images based on major axis direction of texture coordinates

旋转可以通过在将它们加载到立方体贴图采样器之前旋转 6 个立方体贴图图像或通过旋转纹理坐标来实现。

如果立方体贴图用作场景中的环境贴图,纹理坐标由方向 vector 获取,那么旋转图像就有意义了。如果立方体贴图包裹在网格上,则可以以正确的方式指定纹理坐标。

关于c++ - OpenGL 立方体贴图面顺序和采样问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55558241/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com