当前位置: 首页 > article >正文

glsl着色器学习(七)

先了解一个矩阵库twgl/m4

是一个4x4 矩阵数学转换函数的库

  1. normalize(a, dst)
    • 将一个向量除以它的欧几里得长度,归一化后返回
    • 参数"a"是一个vec3(三维向量)
    • 参数"dst"是用来接收结果的,如果不传,则创建一个新的
  2. identity(dst)
    • 创建一个n × n 的单位矩阵
    • 参数"dst"是用来接收结果的,如果不传,则返回一个新的n × n 的单位矩阵
  3.  translate(m, v, dstopt)
    • 将给定的 4×4 矩阵转换为给定的向量 v
    • 返回已转换的矩阵
  4.  rotateX(m, angleInRadians, dstopt)
    • 将给定的4 × 4矩阵绕x轴旋转给定的角度。
  5. rotateY(m, angleInRadians, dstopt)
    • 将给定的4 × 4矩阵绕y轴旋转给定的角度。
  6. perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dstopt)
    • 在给定视锥体的角度高度、纵横比以及近剪裁平面和远剪裁平面的情况下,计算 4×4 透视转换矩阵。参数定义沿负 z 方向延伸的视锥体。给定的角度是平截体的垂直角度,水平角度确定以产生给定的纵横比。参数 near 和 far 是到 near 和 far 剪切平面的距离。请注意,near 和 far 不是 z 坐标,而是沿负 z 轴的距离

let texUnit = 6;
gl.activeTexture(gl.TEXTURE0 + texUnit);
gl.bindTexture(gl.TEXTURE_2D, checkerTexture);
gl.uniform1i(diffuseLoc, texUnit);

texUnit = 3;
gl.activeTexture(gl.TEXTURE0 + texUnit);
gl.bindTexture(gl.TEXTURE_2D, decalTexture);
gl.uniform1i(decalLoc, texUnit);

gl.uniform3fv(lightDirLoc, m4.normalize([1, 5, 8]));

const projection = m4.perspective(
  60 * Math.PI / 180,  // fov
  gl.canvas.clientWidth / gl.canvas.clientHeight,  // aspect
  0.1,  // near
  10,   // far
);
gl.uniformMatrix4fv(projectionLoc, false, projection);

// draw center cube

let modelView = m4.identity();
modelView = m4.translate(modelView, 0, 0, -4);
modelView = m4.xRotate(modelView, 0.5);
modelView = m4.yRotate(modelView, 0.5);

gl.uniformMatrix4fv(modelViewLoc, false, modelView);

gl.uniform4fv(diffuseMultLoc, [0.7, 1, 0.7, 1]);

gl.drawElements(
    gl.TRIANGLES,
    36,                // num vertices to process
    gl.UNSIGNED_SHORT, // type of indices
    0,                 // offset on bytes to indices
);

// draw left cube

modelView = m4.identity();
modelView = m4.translate(modelView, -3, 0, -4);
modelView = m4.xRotate(modelView, 0.5);
modelView = m4.yRotate(modelView, 0.8);

gl.uniformMatrix4fv(modelViewLoc, false, modelView);

gl.uniform4fv(diffuseMultLoc, [1, 0.7, 0.7, 1]);

gl.drawElements(
    gl.TRIANGLES,
    36,                // num vertices to process
    gl.UNSIGNED_SHORT, // type of indices
    0,                 // offset on bytes to indices
);

// draw right cube

modelView = m4.identity();
modelView = m4.translate(modelView, 3, 0, -4);
modelView = m4.xRotate(modelView, 0.6);
modelView = m4.yRotate(modelView, -0.6);

gl.uniformMatrix4fv(modelViewLoc, false, modelView);

gl.uniform4fv(diffuseMultLoc, [0.7, 0.7, 1, 1]);

gl.drawElements(
    gl.TRIANGLES,
    36,                // num vertices to process
    gl.UNSIGNED_SHORT, // type of indices
    0,                 // offset on bytes to indices
);

设置纹理单元和绑定纹理

  1. let texUnit = 6; gl.activeTexture(gl.TEXTURE0 + texUnit);
    1. 定义一个纹理单元编号为 6。然后使用 activeTexture函数激活纹理单元 TEXTURE0+ 6,这表示后续对纹理的操作将针对这个特定的纹理单元进行
  2. gl.bindTexture(gl.TEXTURE_2D, checkerTexture);
    1. 将之前创建的棋盘格纹理(checkerTexture)绑定到当前激活的纹理单元上
  3. gl.uniform1i(diffuseLoc, texUnit);
    1. 通过 diffuseLoc(之前获取的统一变量位置)设置片元着色器中的纹理采样器对应的纹理单元编号为 6。这样片元着色器就知道从哪个纹理单元获取基本颜色纹理。

设置光照方向

  1. gl.uniform3fv(lightDirLoc, m4.normalize([1, 5, 8]));
    1. 通过 lightDirLoc(之前获取的统一变量位置)设置片元着色器中的光照方向为经过归一化处理后的向量 [1, 5, 8]。这将影响片元着色器中的光照计算。

设置投影矩阵

  1. const projection = m4.perspective(60 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 10);
    1. 创建一个透视投影矩阵。参数分别为视野角度(60 度转换为弧度)、画布的宽高比、近裁剪平面距离(0.1)和远裁剪平面距离(10)。
  2. gl.uniformMatrix4fv(projectionLoc, false, projection);
    1. 通过 projectionLoc(之前获取的统一变量位置)将创建的投影矩阵上传到顶点着色器中的 projection统一变量,用于将顶点从视图空间转换到裁剪空间

绘制立方体

  1. let modelView = m4.identity();
    1. 创建一个初始的模型视图矩阵为单位矩阵。
  2. modelView = m4.translate(modelView, 0, 0, -4);
    1. 对模型视图矩阵进行平移操作,将立方体沿 Z 轴负方向移动 -4 个单位,确定其在世界空间中的位置。
  3. modelView = m4.xRotate(modelView, 0.5) 和 modelView = m4.yRotate(modelView, 0.5);
    1. 分别绕 X 轴和 Y 轴旋转模型视图矩阵,旋转角度分别为 0.5。
  4. gl.uniformMatrix4fv(modelViewLoc, false, modelView)
    1. 通过 modelView(之前获取的统一变量位置)将更新后的模型视图矩阵上传到顶点着色器中的 modelView 统一变量,用于将顶点从模型空间转换到视图空间。
  5. gl.uniform4fv(diffuseMultLoc, [0.7, 1, 0.7, 1]);
    1. 设置片元着色器中的 diffuseMultLoc(基本颜色纹理缩放因子)为 [0.7, 1, 0.7, 1],用于调整中心立方体的颜色。
  6. gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
    1. 使用索引缓冲中的数据绘制三角形,绘制模式为 gl.TRIANGLES,处理 36 个顶点索引,索引数据类型为无符号短整型,偏移量为 0。这将绘制出中心的立方体
  7. 左边和右边立方体绘制也是同样的道理,左边立方体沿着X轴负方向移动了3个单位长度,右边立方体沿着X轴正方向移动了3个单位长度。

完结撒花!!!我们了解其渲染过程即可,更多是编辑顶点着色器和片元着色器的内容,对webgl封装较好的上层应用库有threejs和babylonjs。大家可自行尝试

知识来源:WebGL 理论基础 (webglfundamentals.org)


http://www.kler.cn/a/290240.html

相关文章:

  • 客户案例 | 如何利用Ansys工具提供互联系统(以及系统的系统),从而使“软件定义汽车”成为可能
  • 运行WHTools批量启动游戏房间工具提示要安装.Net Framework3.5解决
  • Java基础-组件及事件处理(下)
  • Node.Js+Knex+MySQL增删改查的简单示例(Typescript)
  • 使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径
  • sql server启用远程连接与修改默认端口
  • 多线程篇(基本认识 - 锁优化)(持续更新迭代)
  • HCIP笔记12-交换(1)
  • Mysql高级篇(上)—— Mysql架构介绍(二)
  • SprinBoot+Vue图书馆预约与占座微信小程序的设计与实现
  • C++string类相关OJ练习(2)
  • 【32项目】基于stm32f103c8t6的智能拐杖(文章末尾含完整代码)
  • MAC打开IDA Pro意外退出
  • 论文辅助笔记:LP_BERT
  • 【60天备战软考高级系统架构设计师——第一天:软件工程概述】
  • ListBox等控件的SelectedItem,SelectedValue,SelectedValuePath属性详解
  • 0904,关联式容器针对于自定义形式的写法(
  • 华为数据之道-读书笔记
  • 全能AI vs 专业AI:AI模型未来之路与市场潜力
  • Express Response类深度解析:全面掌握属性与方法,提升开发效率
  • Win 11补丁让AMD成亲儿子,性能最高提升35%
  • 神策SDK不支持Windows客户端全埋点,怎么实现用户统计分析?
  • JDK源码分析:HashMap
  • kubeadm部署 Kubernetes(k8s) 高可用集群【V1.28 】
  • net、udp、tcp
  • Linux之多线程概念