纹理单元
上节中通过采样器(Sampler)将纹理对象传给片段着色器
uniform sampler2D u_Sampler;
GLSL内建的texture函数来采样纹理的颜色,它第一个参数是纹理采样器,第二个参数是对应的纹理坐标。输出的是纹理的(插值)纹理坐标上的(过滤后的)颜色。
sampler2D是个uniform变量,为了片段着色器中可以设置多个纹理,给纹理采样器分配的是一个位置值。一个纹理的位置值通常称为一个纹理单元(Texture Unit)。默认纹理单元是0,它是默认的激活纹理单元。
let texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);// 绑定纹理对象到激活的纹理单元
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// 纹理放大方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);// 纹理缩小方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);// 纹理水平填充方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);// 纹理垂直填充方式
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this._image);
gl.uniform1i(sampler, 0);
let texture2 = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture2);// 绑定纹理对象到激活的纹理单元
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// 纹理放大方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);// 纹理缩小方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);// 纹理水平填充方式
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);// 纹理垂直填充方式
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image2);
gl.uniform1i(sampler2, 1);
我们可以一次绑定多个纹理,首先激活对应的纹理单元,WebGL总共有32个纹理单元可以使用(从gl.TEXTURE0到gl.TEXTURE31),接下来的使用glBindTexture函数绑定这个纹理到当前激活的纹理单元。
位置偏移
例如贴花的位置是要在方块的*并缩小展示出来。可以在原UV的基础上进行缩放偏移。
v_TexCoord1.x = (a_TexCoord.x - 0.5 * (1.0-0.25) ) * 4.0;
v_TexCoord1.y = (a_TexCoord.y - 0.5 * (1.0-0.25) ) * 4.0;
表示缩小4倍在(0.5,0.5)区域显示。
颜色混合
混合模式的公式
片段着色器中
vec4 acolor = texture2D(u_Sampler, v_TexCoord);
vec4 bcolor = texture2D(u_Sampler2, v_TexCoord1);
gl_FragColor = vec4(bcolor.a * bcolor.rgb + (1.0 - bcolor.a) * acolor.rgb ,1.0);
u_Sampler为底图的采样器相当于目标颜色(它会先进入颜色缓冲),u_Sampler2为贴花纹理的采样器相当于源颜色向量。