顶点着色器尺寸修改
<canvas id="canvas"></canvas>
<!-- 顶点着色器 -->
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
attribute float a_PointSize;
void main() {
// 点位
gl_Position = a_Position;
// 尺寸
gl_PointSize = a_PointSize;
}
</script>
<!-- 片元着色器 -->
<script id="fragmentShader" type="x-shader/x-fragment">
void main(){
gl_FragColor = vec4(1,1,0,1);
}
</script>
<script type="module">
// 这里的 utils.js 参考之前博文,不做重复阐述
import { initShaders } from "./utils.js";
const canvas = document.querySelector("#canvas");
canvas.width = 200;
canvas.height = 200;
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
// 三维画笔
const gl = canvas.getContext("webgl");
// 初始化着色器
initShaders(gl, vsSource, fsSource);
// 在 js 中 获取 attribute 变量
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
const a_PointSize = gl.getAttribLocation(gl.program, "a_PointSize");
// 存储顶点数据的数组
const a_points = [
{ x: 0, y: 0, size: 10 },
];
render();
// 渲染方法
function render() {
gl.clearColor(0, 0, 0, 1); // 声明颜色 rgba
gl.clear(gl.COLOR_BUFFER_BIT); // 刷底色
a_points.forEach(({ x, y, size }) => {
gl.vertexAttrib2f(a_Position, x, y);
gl.vertexAttrib1f(a_PointSize, size); // 这里修改尺寸大小
gl.drawArrays(gl.POINTS, 0, 1);
});
}
// 鼠标点击事件
canvas.addEventListener("click", ({ clientX, clientY }) => {
const { left, top, width, height } = canvas.getBoundingClientRect();
const [cssX, cssY] = [clientX - left, clientY - top];
// 解决坐标原点位置的差异
const [halfWidth, halfHeight] = [width / 2, height / 2];
const [xBaseCenter, yBaseCenter] = [
cssX - halfWidth,
cssY - halfHeight,
];
// 解决y方向的差异
const yBaseCenterTop = -yBaseCenter;
// 解决坐标基底的差异
const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];
const size = Math.random() * 50 + 10;
a_points.push({ x, y, size });
render();
});
</script>
- 这个和顶点位置的修改是类似的,上面的a_PointSize 是一个浮点类型的变量
- 在上面的案例中,无论是控制点位的尺寸,还是控制点位的位置,实际上都是对attribute变量的操控
- 那我们如果想要再改变顶点的颜色呢?那就不能再用attribute限定符了,因为attribute限定符限定的就是顶点相关的数据
顶点着色器颜色改变
- 首先,限定颜色变量的限定符叫uniform
- 基于上述代码结构,下面只添加或修改关键部分代码
1 )在片元着色器脚本中定义相关代码
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_FragColor;
void main() {
gl_FragColor = u_FragColor;
}
</script>
- 在片元着色器里把控制顶点颜色的变量暴露出来
- 第一行的precision mediump float 是对浮点数精度的定义,mediump 是中等精度的意思,这个必须要有,不然画不出东西来
- 上面的uniform就是咱们刚才说过的限定符,vec4是4维的变量类型,u_FragColor就是变量名
2 )在js中获取片元着色器暴露出的uniform变量
<script type="module">
const u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor'); // 关键代码
</script>
- 上面的 getUniformLocation() 方法就是用于获取片元着色器暴露出的 uniform 变量的
- 其第一个参数是程序对象,第二个参数是变量名
- 这里的参数结构和获取attribute变量的 getAttributeLocation() 方法是一样的
3 )修改uniform 变量
// 设置随机颜色
const color = new Float32Array([
Math.random(),
Math.random(),
Math.random(),
1.0
]);
gl.uniform4fv(u_FragColor, color); // 在合适的地方进行修改:render方法中的 arr.forEach 循环中处理
- 在上面我们使用 uniform4fv() 方法修改的顶点颜色,也可以用 uniform4f() 方法一个个的写参数
- uniform4f 中,4 是有4个数据,f 是float 浮点类型,就是r、g、b、a 这四个颜色数据, 如:gl.uniform4f(u_FragColor,1.0,1.0,0.0,1.0);
- uniform4fv 中,4f 的意思和上面一样,v 是vector 矢量的意思,这在数学里就是向量的意思。由之前的4f可知,这个向量由4个浮点类型的分量构成
- 在修改uniform变量的时候,这两种写法是一样的
gl.uniform4f(u_FragColor,1.0,1.0,0.0,1.0); //等同于 const color=new Float32Array([1.0,1.0,0.0,1.0]); gl.uniform4fv(u_FragColor,color);- uniform4f() 和uniform4fv() 也有着自己的同族方法,其中的4 可以变成1|2|3
- uniform4fv() 方法的第二个参数必须是Float32Array 数组,不要使用普通的 Array 对象
- Float32Array 是一种32 位的浮点型数组,它在浏览器中的运行效率要比普通的 Array 高很多
6273



被折叠的 条评论
为什么被折叠?



