采样器采样数据

纹理

​ 纹理是一个2D图片(甚至也有1D和3D的纹理),可以用来添加物体的细节。因此可以在一张图片上插入非常多的细节,这样就可以让物体非常精细而不用指定额外的顶点。除了图像以外,纹理也可以被用来储存大量的数据,这些数据可以发送到着色器上。纹理采样的本质是利用采样器读取数据,所读取的数据不一定是作为纹理渲染。

采样

​ 为了能够把纹理映射到三角形上,需要指定三角形的每个顶点各自对应纹理的哪个部分。这样每个顶点就会关联着一个纹理坐标(UV坐标),用来标明该从纹理图像的哪个部分采样。之后在图形的其它片段上进行片段插值。纹理坐标在x和y轴上,范围为0到1之间(2D)。使用纹理坐标获取纹理颜色叫做采样。纹理坐标起始于(0, 0),也就是纹理图片的左下角,终始于(1, 1),即纹理图片的右上角。下面的图片展示了如何把纹理坐标映射到三角形上的。

image-20230105085456442

纹理单元

一个纹理的位置值通常称为一个纹理单元。一个纹理的默认纹理单元是0,它是默认的激活纹理单元。纹理单元的主要目的是让我们在着色器中可以使用多于一个的纹理。通过把纹理单元赋值给采样器,可以一次绑定多个纹理,只要我们首先激活对应的纹理单元。激活纹理单元之后,接下来绑定这个纹理到当前激活的纹理单元,纹理单元GL_TEXTURE0默认总是被激活。

1
2
3
4
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);

定义哪个采样器对应哪个纹理单元,只需要设置一次即可

1
2
glUniform1i(Texture1ID, 0);
glUniform1i(Texture2ID, 1);

作为其他数据采样

先利用phrtest03的函数自定义一组纹理数据:

1
2
3
4
float cube1[4] = { 1.0, -1.0,1.0,0.8};
float cube2[4] = { 0.7, 0.8,1.0,0.1};
float cube3[4] = { -1.0, 0.5, 1.0,0.3};
float cube4[4] = { 0.4, 0.8,1.0,0.6};

该纹理在1:1的四边形上分成了四块

纹理坐标:

1
2
3
4
5
6
static const GLfloat tex_data[] = {
0.0f,1.0f,
1.0f,1.0f,
1.0f,0.0f,
0.0f,0.0f
};

画四个柱形,分别在四块进行采样,因此现在顶点着色器中对UV坐标进行变换(变换方式详见之前的分屏变换)

1
2
3
4
5
6
7
8
9
10
11
  UV = vertexUV;
if (position.x<=-0.2) {
UV.x = UV.x /2.0;UV.y = UV.y /2.0-0.001;
}else{
if (position.x<0.1){
UV.x = UV.x /2.0+0.5; UV.y = UV.y /2.0;
}else{
if (position.x<0.4){
UV.x = UV.x /2.0;UV.y = UV.y /2.0+0.5;
}else{
UV.x = UV.x /2.0+0.5;UV.y = UV.y /2.0+0.5; }}}

在顶点着色器中设置采样器(如果只有一个纹理可以和片段着色器中的采样器同名),将纹理数据的第四个值作为y轴坐标,注意先声明uniform sampler2D sampler;

1
2
3
4
5
float y=texture2D(sampler, UV).a;
if(position.y>0.0){
gl_Position = vec4(position.x,y,position.z,1);
}else{
gl_Position = vec4(position,1);}

因为要设置光照,在片段着色器中将纹理数据的第四个值作为颜色,将前三个值作为法线数据

1
2
3
4
float color=texture2D( sampler, UV ).a;
vec3 MaterialDiffuseColor=vec3(color,0.0,0.0);
vec3 normal = texture2D( sampler, UV ).rgb;
vec3 Normal_cameraspace = ( V * M * vec4(normal,0)).xyz;

运行结果:

image-20230105094422261

因此纹理数据可以作为任意顶点数据使用,采样器在顶点着色器和片段着色器都可以使用。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信