在webgl中纹理有很多的用途,可以进行数据的保存、贴图等方面的用途。
下面我记录一下在webgl中,最简单纹理的使用,参考文章为一叶斋 | WebGL 纹理详解
本文使用图片也来自一叶斋 | WebGL 纹理详解 中demo提供的
1、首页创建顶点、片元着色器
const VERTEX = `attribute vec2 a_position;
varying vec2 vPos;
void main(){
vPos = a_position;
gl_Position = vec4(2.0 * a_position - 1.0, 0.0, 1.0);
}`
const FRAGEMENT = `precision mediump float;
varying vec2 vPos;
uniform sampler2D u_img;
// uniform sampler2D tMap;
void main() {
vec4 color = texture2D(u_img, vPos*5.0);
gl_FragColor = color;
}
`
const vertexShader = gl.createShader(gl.VERTEX_SHADER)!;
gl.shaderSource(vertexShader, VERTEX);
gl.compileShader(vertexShader);
const fragShader = gl.createShader(gl.FRAGMENT_SHADER)!;
gl.shaderSource(fragShader, FRAGEMENT);
gl.compileShader(fragShader);
2、创建程序
const program = gl.createProgram()!;
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
gl.useProgram(program);
3、创建缓冲区并传递顶点
const posBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(positions),
gl.STATIC_DRAW
);
4、获取位置信息并启用
const aPosition = gl.getAttribLocation(program, 'a_position');
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition);
5、创建纹理绑定纹理
//加载图片
const img = await loadImg(img_url)
const texture = gl.createTexture();
// 设置预处理函数,由于图片坐标系和WebGL坐标的Y轴是反的,这个设置可以将图片Y坐标翻转一下
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
// 激活指定纹理单元,WebGL有多个纹理单元,因此在Shader中可以使用多个纹理
gl.activeTexture(gl.TEXTURE0);
// 将纹理绑定到当前上下文
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
// 设置纹理的一些参数
// gl.TEXTURE_WRAP_S 纹理在X方向的包裹方式、
// 取值有gl.REPEAT、gl.MIRRORED_REPEAT、gl.CLAMP_TO_EDGE
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
// gl.TEXTURE_WRAP_T 纹理在Y方向的包裹方式、
// 取值有gl.REPEAT、gl.MIRRORED_REPEAT、gl.CLAMP_TO_EDGE
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// 纹理缩小时过滤方式,可以取值为gl.LINEAR、gl.NEAREST
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// 纹理方大时过滤方式,可以取值为gl.LINEAR、gl.NEAREST
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST )
// 解除纹理绑定
gl.bindTexture(gl.TEXTURE_2D, null);
6、绘制
gl.drawArrays(gl.TRIANGLE_FAN, 0, positions.length / 2);