我正在写一个考虑到两个表面的折射着色器.因此,我使用FBO渲染纹理的深度和法线,以及用于表示环境的立方体贴图.我需要使用纹理中存储的法线值来从立方体贴图中获取值,以获得后表面的折射法线.
只要我不尝试从已从纹理中检索其值的矢量访问立方体贴图,立方体贴图就可以完美地工作.
这是一个失败的最小片段着色器.颜色保持绝对黑色.我确信对纹理2D的调用会返回非零值:如果我尝试显示方向中包含的纹理颜色(表示法线),我会得到一个完美的彩色模型.无论我使用"方向"向量进行何种操作,它都会继续失败.
uniform samplerCube cubemap;
uniform sampler2D normalTexture;
uniform vec2 viewportSize;
void main()
{
vec3 direction = texture2D(normalTexture, gl_FragCoord.xy/viewportSize).xyz;
// direction = vec3(1., 0., 0) + direction; // fails as well!!
vec4 color = textureCube(cubemap, direction);
gl_FragColor = color;
}
Run Code Online (Sandbox Code Playgroud)
以下是显示为颜色的矢量"方向"的值,只是证明它们不是空的!
这是上面着色器(只是茶壶)的结果.

虽然这段代码完美无缺:
uniform samplerCube cubemap;
uniform vec2 viewportSize;
varying vec3 T1;
void main()
{
vec4 color = textureCube(cubemap, T1);
gl_FragColor = color;
}
Run Code Online (Sandbox Code Playgroud)

每当我访问采样器立方体值时,我都想不出为什么我的颜色会保持黑色的任何原因!
只是为了完整起见,即使我的立方体贴图有效,这里有用于设置它的参数:glGenTextures(1,&mTextureId);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureId);
// Set parameters
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
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);
Run Code Online (Sandbox Code Playgroud)
除非我错过了某些重要的事情,否则我认为它可能是一个驱动程序错误.我没有任何显卡,我使用的是英特尔酷睿i5处理器芯片组.
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)
Run Code Online (Sandbox Code Playgroud)
任何关于为什么会发生这种情况的想法,或者你有解决方法吗?
编辑:这是我的着色器类绑定纹理的方式
4 textures to bind
Bind texture 3 on texture unit unit 0
Bind to shader uniform: 327680
Bind texture 4 on texture unit unit 1
Bind to shader uniform: 262144
Bind texture 5 on texture unit unit 2
Bind to shader uniform: 393216
Bind texture 9 on texture unit unit 3
Bind to shader uniform: 196608
Run Code Online (Sandbox Code Playgroud)
纹理3和4是深度,5是法线贴图,9是立方体贴图.
以及执行绑定的代码:
void Shader::bindTextures() {
dinf << m_textures.size() << " textures to bind" << endl;
int texture_slot_index = 0;
for (auto it = m_textures.begin(); it != m_textures.end(); it++) {
dinf << "Bind texture " << it->first<< " on texture unit unit "
<< texture_slot_index << std::endl;
glActiveTexture(GL_TEXTURE0 + texture_slot_index);
glBindTexture(GL_TEXTURE_2D, it->first);
// Binds to the shader
dinf << "Bind to shader uniform: " << it->second << endl;
glUniform1i(it->second, texture_slot_index);
texture_slot_index++;
}
// Make sure that the texture unit which is left active is the number 0
glActiveTexture(GL_TEXTURE0);
}
Run Code Online (Sandbox Code Playgroud)
m_textures是纹理ID到统一ID的映射.
您似乎没有为法线贴图和立方体贴图使用单独的纹理单元.一切都默认为纹理单元0.您需要以下内容:
uniform sampler2D norm_tex;
uniform samplerCube cube_tex;
Run Code Online (Sandbox Code Playgroud)
在着色器中.texture在使用(3.2+)核心配置文件时,纹理查找应该只使用'重载' 功能.使用(3.3+),您还可以使用采样器对象.
生成并绑定纹理以分离纹理单元:
... generate 'norm_tex' and 'cube_tex' ...
glActiveTexture(GL_TEXTURE0);
... bind 'norm_tex' and set parameters ...
glActiveTexture(GL_TEXTURE1);
... bind 'cube_tex' and set parameters ...
... glUseProgram(prog); ...
glUniform1i(glGetUniformLocation(prog, "norm_map"), 0);
glUniform1i(glGetUniformLocation(prog, "cube_map"), 1);
Run Code Online (Sandbox Code Playgroud)