web GL绘制点
图元 :WebGL 能够绘制的根基图形元素,包罗三种:点、线段、三角形。
片元:可以理解为像素,像素着色阶段是在片元着色器中。
裁剪坐标系:裁剪坐标系是极点着色器中的 gl_Position 内置变量接收到的坐标地址的坐标系。
设备坐标系:别名 NDC 坐标系,是裁剪坐标系各个分量对 w 分量相除得到的坐标系,特点是 x、y、z 坐标分量的取值范畴都在 【-1,1】之间,可以将它理解为边长为 2 的正方体,坐标系原点在正方体中心。
二、GLSL
gl_Position:内置变量,用来设置极点的裁剪坐标系坐标,包罗 X, Y, Z,,W 四个坐标分量。极点着色器接收到这个坐标之后,对它进行透视除法,即将各个分量同时除以 W,转换成 NDC 坐标,NDC 坐标每个分量的取值范畴都在【-1, 1】之间,GPU 获取这个属性值作为极点的最终位置进行绘制。
gl_PointSize:内置变量,用来设置极点巨细。只有在绘制图元是点的时候才会生效。
gl_FragColor:片元(像素)颜色,包罗 R, G, B, A 四个颜色分量,且每个分量的取值范畴在【0,1】之间,GPU 获取这个值作为像素的最终颜色进行着色。
gl_FragColor:内置变量,用来设置像素颜色。
attribue 变量:只能在极点着色器中界说。
uniform 变量:既可以在极点着色器中界说,也可以在片元着色器中界说。
最后一种变量类型 varing 变量:它用来从极点着色器中往片元着色器通报数据。使用它我们可以在极点着色器中声明一个变量并对其赋值,颠末插值措置惩罚惩罚后,在片元着色器中取出插值后的值来使用。
vec4:4 维向量,包罗四个浮点元素的容器类型,vec 是 vector(向量)的单词简写,vec4 代表包罗 4 个浮点数的向量。别的,还有 vec2、vec3 等类型,代表包罗2个或者3个浮点数的容器。
precision:精度设置限定符,使用此限定符设置完精度后,之后所有该数据类型都将沿用该精度,除非单独设置。
运算符:向量的对应位置进行运算,得到一个新的向量。
vec * 浮点数:vec2(x, y) * 2.0 = vec(x * 2.0, y * 2.0)。
vec2 * vec2:vec2(x1, y1) * vec2(x2, y2) = vec2(x1 * x2, y1 * y2)。
加减乘除法则根基一致。但是要注意一点,如果参预运算的是两个 vec 向量,那么这两个 vec 的维数必需不异。
GLSL 中 gl_Position 所接收的坐标地址坐标系是裁剪坐标系 ,差别于我们的浏览器窗口坐标系。所以当我们赋予 gl_Position 位置信息的时候,需要对其进行转换才华正确显示。
createShader:创建着色器东西
shaderSource:供给着色器源码
compileShader:编译着色器东西
createProgram:创建着色器措施
attachShader:绑定着色器东西
linkProgram:链接着色器措施
useProgram:启用着色器措施
getAttribLocation:找到着色器中的 attribute 变量地点。
getUniformLocation:找到着色器中的 uniform 变量地点。
vertexAttrib2f:给 attribute 变量通报两个浮点数。
uniform4f:给uniform变量通报四个浮点数。
drawArrays: 用指定的图元进行绘制。
gl.drawArrays 是执行绘制的 API,上面示例中的第一个参数 gl.POINTS 代表我们要绘制的是点图元,第二个参数代表要绘制的极点的起始位置,第三个参数代表极点绘制个数。
gl.POINTS: 将绘制图元类型设置成点图元。
02代码 <!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL 绘制点</title>
<script type="x-shader/x-vertex">
//设置浮点数精度为中等精度
precision mediump float;
// 接收点在canvas坐标系上的坐标(x,y)
attribute vec2 a_Position;
// 接受canvas 的宽高尺寸
attribute vec2 a_Screen_Size;
void main(){
//start 将屏幕坐标系转化为裁剪坐标(裁剪坐标系)
vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
position = position * vec2(1.0, -1.0);
gl_Position = vec4(position, 0.0, 1.0);
//end 将屏幕坐标系转化为裁剪坐标(裁剪坐标系)
//声明要绘制的点的巨细。
gl_PointSize = 10.0;
}
</script>
<script type="x-shader/x-fragment">
//设置浮点数精度为中等精度
precision mediump float;
//接收 JavaScript 传过来的颜色值(RGBA)。
uniform vec4 u_Color;
void main(){
//将普通的颜色暗示转化为 WebGL 需要的暗示方法,即将【0-255】转化到【0,1】之间。
vec4 color = u_Color / vec4(255, 255, 255, 1);
gl_FragColor = color;
}
</script>
</head>
<body>
<canvas></canvas>
</body>
</html>
<script>
function createShaderFromScript(gl, mode, id) {
// 获取着色器源码
var shaderSource = document.getElementById(id).innerHTML;
// 创建着色器东西
var shader = gl.createShader(mode);
// 将源码分配给着色器东西
gl.shaderSource(shader,shaderSource);
// 编译着色器
gl.compileShader(shader);
return shader;
}
function createProgram(gl, vertexShader, fragmentShader) {
var program = gl.createProgram();
// 将极点着色器挂载在着色器措施上。
gl.attachShader(program, vertexShader);
//将片元着色器挂载在着色器措施上。
gl.attachShader(program, fragmentShader);
//链接着色器措施
gl.linkProgram(program);
return program;
}
var canvas = document.getElementById(‘canvas‘);
var gl = canvas.getContext(‘webgl‘) || canvas.getContext("experimental-webgl");
<!--region 创建着色器东西-->
var vertexShader = createShaderFromScript(gl, gl.VERTEX_SHADER, ‘vertexShader‘);
var fragmentShader = createShaderFromScript(gl, gl.FRAGMENT_SHADER, ‘fragmentShader‘)
<!--endregion-->
<!--region 创建着色器措施-->
//创建着色器措施
let program = createProgram(gl, vertexShader, fragmentShader);
// 使用刚刚创建好的着色器措施
gl.useProgram(program);
<!--endregion-->
//找到极点着色器中的变量a_Position
var a_Position = gl.getAttribLocation(program, ‘a_Position‘);
//找到极点着色器中的变量a_Screen_Size
var a_Screen_Size = gl.getAttribLocation(program, ‘a_Screen_Size‘);
//找到片元着色器中的变量u_Color
var u_Color = gl.getUniformLocation(program, ‘u_Color‘);
//为极点着色器中的 a_Screen_Size 通报 canvas 的宽高信息
gl.vertexAttrib2f(a_Screen_Size, canvas.width, canvas.height);
//存储点击位置的数组。
var points = [];
function randomColor(){
return {
r: Math.ceil(Math.random() * 255),
g: Math.ceil(Math.random() * 255),
b: Math.ceil(Math.random() * 255),
a: Math.ceil(Math.random()),
};
}
canvas.addEventListener(‘click‘,e=>{
var x = e.pageX;
var y = e.pageY;
var color = randomColor();
points.push({x,y,color});
gl.clearColor(0, 0, 0, 1.0);
//用上一步设置的清空画布颜色清空画布。
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < points.length; i++) {
let color = points[i].color;
gl.uniform4f(u_Color, color.r, color.g, color.b, color.a);
//为极点着色器中的 a_Position 通报极点坐标。
gl.vertexAttrib2f(a_Position, points[i].x, points[i].y);
// 绘制点
gl.drawArrays(gl.POINTS, 0, 1);
}
})
//设置清空画布颜色为黑色。
gl.clearColor(0.0,0.0,0.0,1.0);
//用上一步设置的清空画布颜色清空画布。
gl.clear(gl.COLOR_BUFFER_BIT);
</script>
vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/30738.html