- 作者:老汪软件技巧
- 发表时间:2024-11-01 21:02
- 浏览量:
webgl介绍什么是webgl
WebGL是一种3D绘图协议,衍生于OpenGLES2.0,可以结合HTML5和JavasSript在网页上绘制和渲染二/三维图形
webgl的应用场景webgl的优势
内嵌在浏览器中,不需要安装任何插件即可运行只需要一个文本编辑器和浏览器,就可以编写三维图形程序
webgl开源框架Three.js: JavaScript 3D WebGL库Babylonjs:Web3D图形引擎KickJs:Web的开源图形和游戏引擎ClayGL:构建可扩展的Web3D应用程序PlayCanvas:网络游戏和3D图形引擎WebGLStudio.is和Litescene.is:开源Web 3D图形编辑器和创建器canvas和webgl的区别
canvas是HTML5新增的一个 DOM 元素
用途:显示 二维 和 三维 的图像
绘制:二维图形可以使用(Canvas APl或 WebGL API)三维图形使用 WebGL API
canvas Api提供二维绘图的方式-》canvas.getContext('2d')webgl Api提供三维绘图的方式-》canvas.getContext('webgl')
webgl程序什么是着色器
着色器就是让开发者自己去编写一段程序,用来代替固定染管线,来处理图像的渲染。
流程介绍:
现在我们来绘制一个点
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="../lib/index.js">script>
head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持canvas
canvas>
body>
html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 着色器
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
// 必须要存在 main 函数
void main() {
// 要绘制的点的坐标
gl_Position = vec4(0.0,0.0,0.0,1.0);
// 点的大小
gl_PointSize = 30.0;
}
`; // 顶点着色器
// gl_Position vec4(0.0,0.0,0.0,1.0) x, y, z, w齐次坐标 (x/w, y/w, z/w)
// gl_FragColor vec4(1.0,0.0,0.0,1.0) r, g, b, a
const FRAGMENT_SHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; // 片元着色器
// 创建着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE) // 指定顶点着色器的源码
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE) // 指定片元着色器的源码
// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)
// 创建一个程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)
// 执行绘制
// 要绘制的图形是什么, 从哪个开始, 使用几个顶点
gl.drawArrays(gl.POINTS, 0, 1);
script>
可以看得出来有从创建着色器、编译着色器、创建程序对象这一块的代码是一定的,可以进行封装
function initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) {
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE) // 指定顶点着色器的源码
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE) // 指定片元着色器的源码
// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)
// 创建一个程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)
return program;
}
绘制多个点
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script src="../lib/index.js">script>
<style>
* {
margin: 0;
padding: 0;
}
canvas{
margin: 50px auto 0;
display: block;
background: yellow;
}
style>
head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持canvas
canvas>
body>
html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
uniform vec4 uPosition;
// 只传递顶点数据
attribute vec4 aPosition;
void main() {
gl_Position = aPosition; // vec4(0.0,0.0,0.0,1.0)
gl_PointSize = 10.0;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
precision mediump float;
uniform vec2 uColor;
void main() {
gl_FragColor = vec4(uColor.r, uColor.g, 0.0,1.0); // vec4
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition');
const uColor = gl.getUniformLocation(program, 'uColor')
const points = []
ctx.onclick = function(ev) {
// 坐标
const x = ev.clientX
const y = ev.clientY
const domPosition = ev.target.getBoundingClientRect();
const domx = x - domPosition.left
const domy = y - domPosition.top;
//计算点在canvas的坐标
/*
0 200 400
-1 0 1
-200 0 200
-1 0 1
需要先 -200 (当前画布的宽度) 然后再 除以 200
1 0 -1
0 200 400
200 0 -200 / 200
需要先让 200 减这个数,然后再 / 200
* */
const halfWidth = ctx.offsetWidth / 2
const halfHeight = ctx.offsetHeight / 2
const clickX = (domx - halfWidth) / halfWidth
const clickY = (halfHeight - domy) / halfHeight
points.push({
clickX, clickY
})
for (let i = 0; i < points.length; i++) {
gl.vertexAttrib2f(aPosition, points[i].clickX, points[i].clickY)
gl.uniform2f(uColor, points[i].clickX, points[i].clickY)
gl.drawArrays(gl.POINTS, 0, 1);
}
}
script>