纹理采样器----纹理坐标
只有纹理坐标,纹理没有作用。
纹理坐标是在顶点着色器中设置,需要传入片段着色器,在片段着色器中需要定义纹理采样器。
然后调用texture函数利用采样器和纹理坐标对纹理进行采样。
我们使用GLSL内建的texture函数来采样纹理的颜色,它第一个参数是纹理采样器,第二个参数是对应的纹理坐标。texture函数会使用之前设置的纹理参数对相应的颜色值进行采样。这个片段着色器的输出就是纹理的(插值)纹理坐标上的(过滤后的)颜色。
绑定纹理采样器到纹理单元
不绑定
当纹理只有一个时,这个纹理单元默认是被激活的,可以不用给采样器指定纹理单元,默认使用的就是第一个纹理。
绑定
当有多个纹理时,如果我们需要选择使,就需要给采样器指定我们需要的纹理单元。
设置采样器和纹理单元的对应关系
片段着色器
#version 330 core
in vec2 textureCoor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main()
{gl_FragColor =texture(texture0,textureCoor);
}
纹理
m_texture0=new QOpenGLTexture(QImage(":/image/tree.png"));//.mirrored());m_texture1=new QOpenGLTexture(QImage(":/image/laugh.png"));
采样器绑定到对应的纹理单元
shaderProgram.setUniformValue("texture0",0);shaderProgram.setUniformValue("texture1",1);
将第一个纹理绑定到第一个纹理单元
m_texture0->bind(0);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
将第二个纹理绑定到第一个纹理单元
m_texture1->bind(1);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
第二个采样器在着色器中没有使用,如果将纹理绑定到第二个采样器,就不会发生采样:
m_texture1->bind(1);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
纹理单元
纹理单元不是纹理对象。
纹理单元是 OpenGL 中负责纹理管理的概念之一,它是一个由硬件实现的状态机,用于在不同的纹理对象和纹理参数之间切换。在渲染过程中,我们可以使用不同的纹理单元,从而使用不同的纹理对象和纹理参数。纹理单元类似于一个数组,其索引就是纹理单元的编号,编号从 0 开始,直到硬件所支持的最大纹理单元数。
一般情况下,在渲染过程中,我们需要先绑定纹理对象到纹理单元上,然后再渲染对应的图形。一个纹理单元可以绑定一个纹理对象,也可以切换到另一个纹理对象。
在 OpenGL 中,使用 `glActiveTexture()` 函数来选择当前的纹理单元。`glActiveTexture()` 函数的参数是纹理单元的编号,例如 `GL_TEXTURE0` 表示纹理单元 0,`GL_TEXTURE1` 表示纹理单元 1,以此类推。
示例代码如下:
```cpp
// 选择纹理单元 0
glActiveTexture(GL_TEXTURE0);
// 绑定纹理对象到纹理单元 0 上
glBindTexture(GL_TEXTURE_2D, textureID);
// 在着色器程序中传递纹理单元号
glUniform1i(glGetUniformLocation(programID, "texture"), 0);
```
在上述示例代码中,我们选择纹理单元 0,然后将纹理对象 `textureID` 绑定到该纹理单元上。然后,我们将纹理单元号 0 传递到着色器程序中的 `texture` uniform 变量中。这样,在渲染过程中,OpenGL 就会从纹理单元 0 中获取相应的纹理对象来渲染。
指定纹理单元的两种方式
OpenGL至少保证有16个纹理单元供你使用,也就是说你可以激活从GL_TEXTURE0到GL_TEXTRUE15。它们都是按顺序定义的,所以我们也可以通过GL_TEXTURE0 + 8的方式获得GL_TEXTURE8。
纹理对象--纹理采样器--纹理单元
纹理单元和纹理采样器是相关概念但并不完全相同。
纹理单元是管理纹理对象的硬件状态机,它是通过指定纹理单元编号来管理不同的纹理对象和纹理参数的。一个纹理单元可以绑定一个纹理对象,并且可以被多个纹理采样器所使用。
纹理采样器是在着色器程序中声明的 uniform 变量,用于在纹理采样过程中控制纹理的采样方式(例如使用线性过滤还是最邻近过滤等)和采样坐标的变换(例如旋转、缩放等)。纹理采样器用于指定在片段着色器中对应的纹理单元,以便于绑定特定的纹理对象。
因此,纹理单元和纹理采样器的作用不同,但它们常常被一起使用。在着色器程序中,我们通过纹理采样器来指定纹理的采样方式和变换方式,然后使用 `glUniform1i()` 函数将该纹理采样器绑定到相应的纹理单元上,从而实现在特定的纹理单元中呈现相应的纹理对象。
纹理采样器通过shader.setUniformValue("xxx",n)绑定到对应的纹理单元;
纹理对象通过bind(n)绑定到对应的纹理单元;
总之,纹理对象设置进入纹理单元;纹理采样器从纹理单元读取纹理对象进行采样。