Opengl学习-立方体贴图踩坑记录
2023/10/25 星期三
昨晚写到了凌晨1点,今早终于查出了问题,写一篇随笔记录一下
- 绑定到特定纹理单元,沿用
TEXTURE_2D
方式:
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
- Cubemap无法生成Mipmap,引发
GL_INVALID_ENUM = 1280
错误
- 可以主动加载多个Mipmap level,在
glTexImage2D
中指定level
参数进行加载,常用于IBL(Image Based Lighting)中的反射贴图 - (不确定)需要设定
GL_TEXTURE_BASE_LEVEL
和GL_TEXTURE_MAX_LEVEL
确定Mipmap level范围
- 在着色器中使用Cubemap
- Uniform 声明:
uniform samplerCube texture0;
- 使用:
vec3 direction = vec3(1.0, 0.0, 0.0);
vec3 cubemap_color = texture(texture0, direction).rgb;
- 注意:不需要额外对方向向量做归一,任意非0的方向向量都可以返回在该方向上的立方体贴图采样
- 使用特定LOD(需要传入多个level的纹理):
float level = 0.5;
vec3 cubemap_color = textureLod(texture0, direction, level).rgb;
对于textureLod,详情见 textureLod - OpenGL 4 Reference Pages
- 面不匹配问题:
- 首先考虑读取时是否需要垂直翻转
- 其次考虑手性,部分天空盒贴图在导出之时用的是右手系,在OpenGL左手系可能出问题
- 立方体面接缝问题:
- 将三个方向的wrap mode均设置为
GL_CLAMP_TO_EDGE
:
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
- 使用
glGetError()
获取错误,有助于发现错误,定位出错位置