返回
让你的浏览器给图片贴上纹理,WebGL轻松实现图片显示
前端
2023-10-28 05:35:18
WebGL,全称 Web Graphics Library,是一个 JavaScript API,用于在浏览器中呈现交互式 3D 图形。WebGL 广泛应用于游戏、可视化和虚拟现实等领域。
在上一节中,我们已经学会了绘制具有渐变色的三角形。本节中,我们将继续为三角形的顶点增加纹理坐标信息,从而使用图片作为纹理来显示图片。
纹理映射
纹理映射是图形学中的一种技术,用于将纹理(例如图片)应用到三维模型的表面上。纹理映射可以使模型看起来更加逼真和细节丰富。
在 WebGL 中,纹理映射可以通过纹理坐标来实现。纹理坐标是一组数字,用于指定纹理在模型表面上的位置和大小。纹理坐标的范围通常为 0 到 1,其中 0 表示纹理的左上角,1 表示纹理的右下角。
实现图片显示
为了在 WebGL 中显示图片,我们需要执行以下步骤:
- 加载图片。
- 创建纹理对象。
- 将图片数据上传到纹理对象。
- 为三角形添加纹理坐标信息。
- 在着色器中使用纹理坐标信息。
- 绘制三角形。
加载图片
图片可以通过 HTML 的 <img>
标签来加载。
<img id="image" src="image.png">
创建纹理对象
纹理对象可以通过 WebGL 的 createTexture()
函数来创建。
var texture = gl.createTexture();
将图片数据上传到纹理对象
图片数据可以通过 WebGL 的 texImage2D()
函数来上传到纹理对象。
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
为三角形添加纹理坐标信息
纹理坐标信息可以通过 WebGL 的 texCoordPointer()
函数来添加。
gl.texCoordPointer(2, gl.FLOAT, 0, textureCoordinates);
在着色器中使用纹理坐标信息
纹理坐标信息可以在着色器中使用 texture2D()
函数来使用。
var color = texture2D(texture, textureCoordinates);
绘制三角形
三角形可以通过 WebGL 的 drawArrays()
函数来绘制。
gl.drawArrays(gl.TRIANGLES, 0, 3);
完整代码
完整的代码如下所示:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
var gl = canvas.getContext("webgl");
// 加载图片
var image = new Image();
image.onload = function() {
// 创建纹理对象
var texture = gl.createTexture();
// 将图片数据上传到纹理对象
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
// 为三角形添加纹理坐标信息
var textureCoordinates = [
0.0, 0.0,
1.0, 0.0,
0.0, 1.0
];
gl.texCoordPointer(2, gl.FLOAT, 0, textureCoordinates);
// 在着色器中使用纹理坐标信息
var vertexShaderSource = `
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
v_texCoord = a_texCoord;
}
`;
var fragmentShaderSource = `
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoord);
}
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// 绘制三角形
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
var positions = [
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
var textureBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
var textureAttributeLocation = gl.getAttribLocation(program, "a_texCoord");
gl.enableVertexAttribArray(textureAttributeLocation);
gl.vertexAttribPointer(textureAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
image.src = "image.png";
</script>
</body>
</html>
运行示例
将上述代码保存为 HTML 文件,然后在浏览器中打开即可看到效果。
本节中,我们学习了如何利用 WebGL 为三角形添加纹理坐标信息,并使用图片作为纹理来显示图片。