对于绘制多个点,并且多个点的颜色需要不一样。单个attribute是不能够完成的,这时候需要多个attribute来实现
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
attribute vec4 a_Color;
//着色器共享
varying vec4 v_Color;
void main(){
gl_Position=a_Position;
gl_PointSize=50.0;
v_Color=a_Color;
}
</script>
多个attribute,需要多个buffer来共享数据。比如颜色数据批量传递给着色器
//颜色数据
const colors = new Float32Array([
1, 0, 0,
0, 1, 0,
0, 0, 1,
]);
//缓冲对象
const colorBuffer = gl.createBuffer();
//绑定缓冲对象
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
//写入数据
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)
//获取attribute 变量
const a_Color = gl.getAttribLocation(gl.program, 'a_Color')
//修改attribute 变量
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 0, 0)
//赋能-批处理
gl.enableVertexAttribArray(a_Color)
按照上面的方式可以绘制不同颜色的点
attribute数据合一
上面这个绘制方式会导致很多的重复代码,不利于代码的维护。我们可以把多个attribute统一。在统一之前需要明白下面的概念
- 数据源:整个合而为一的数据source
- 元素字节数:32位浮点集合中每个元素的字节数
- 类目:一个顶点对应一个类目,也就是上面source中的每一行
- 系列:一个类目中所包含的每一种数据,比如顶点位置数据、顶点颜色数据
- 系列尺寸:一个系列所对应的向量的分量数目
- 类目尺寸:一个类目中所有系列尺寸的总和
- 类目字节数:一个类目的所有字节数量
- 系列元素索引位置:一个系列在一个类目中,以集合元素为单位的索引位置
- 系列字节索引位置:一个系列在一个类目中,以字节为单位的索引位置
- 顶点总数:数据源中的顶点总数
具体代码如下所示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<!-- 定点着色器 -->
<script id="vertexShader" type="x-shader/x-vertext">
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main () {
gl_Position = a_Position;
gl_PointSize = 50.0;
v_Color = a_Color;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_Color;
void main () {
gl_FragColor = v_Color;
}
</script>
<script type="module">
import { initShaders } from "./jsm/Utils.js";
const canves = document.querySelector('#canvas');
canves.width = window.innerWidth
canves.height = window.innerHeight
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
const gl = canves.getContext('webgl')
initShaders(gl, vsSource, fsSource)
const a_Position = gl.getAttribLocation(gl.program, 'a_Position')
const a_Color = gl.getAttribLocation(gl.program, 'a_Color')
// 创建缓冲区
const vertextBuffer = gl.createBuffer();
// 绑定缓冲区
const source = new Float32Array([
0,0.2,0,1,0,0,1,
0.2,0,0,0,1,0,1,
-0.2,0,0,0,0,1,1
])
// 元素字节数量 4各界
const elementBytes = source.BYTES_PER_ELEMENT
// 系统尺寸
// 位置尺寸
const verticeSize = 3;
// 颜色尺寸
const colorSize = 4;
// 类目尺寸
const categorySize = verticeSize +colorSize;
// 类目字节数
const categoryBytes = categorySize *elementBytes
// 位置索引位置
const verticeByteIndex = 0;
// 颜色索引位置
const colorByteIndex = verticeSize *elementBytes
// 顶点的数量
const sourceSize = source.length /categorySize
gl.bindBuffer(gl.ARRAY_BUFFER,vertextBuffer)
gl.bufferData(gl.ARRAY_BUFFER, source, gl.STATIC_DRAW)
// gl.vertexAttrib3f(a_Position,0,0,0)
gl.vertexAttribPointer(a_Position,verticeSize , gl.FLOAT,false,categoryBytes,verticeByteIndex)
gl.enableVertexAttribArray(a_Position)
gl.vertexAttribPointer(a_Color,colorSize , gl.FLOAT,false,categoryBytes,colorByteIndex)
gl.enableVertexAttribArray(a_Color)
gl.clearColor(0,0,0,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.POINTS,0,3)
</script>
</html>
网友评论