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

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,  // fovgl.canvas.clientWidth / gl.canvas.clientHeight,  // aspect0.1,  // near10,   // far
);
gl.uniformMatrix4fv(projectionLoc, false, projection);// draw center cubelet 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 processgl.UNSIGNED_SHORT, // type of indices0,                 // offset on bytes to indices
);// draw left cubemodelView = 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 processgl.UNSIGNED_SHORT, // type of indices0,                 // offset on bytes to indices
);// draw right cubemodelView = 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 processgl.UNSIGNED_SHORT, // type of indices0,                 // 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)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 从源码角度分析 Kotlin by lazy 的实现
  • accelerate一些类和函数说明二
  • 集合及映射
  • linux批量解压tar.gz文件
  • 动态规划-最大子数组和
  • STM32的CRC校验(基于HAL库)
  • c++面向对象程序设计中的二义性及解决办法--郭妍论文
  • Electron 项目实战 03: 实现一个截图功能
  • Spark框架
  • 【kubernetes】持久化存储 —— PV / PVC
  • 打开mdk的configuration wizard界面
  • Qt:玩转QPainter序列九(文本,文本框,填充)
  • SpringBoot Web请求响应
  • 极盾故事|某金融租赁机构应用数据保护新策略:“动态脱敏”“二次授权”
  • Trm理论 2(Word2Vec)
  • 【Linux系统编程】快速查找errno错误码信息
  • bearychat的java client
  • canvas绘制圆角头像
  • isset在php5.6-和php7.0+的一些差异
  • javascript从右向左截取指定位数字符的3种方法
  • PAT A1050
  • scrapy学习之路4(itemloder的使用)
  • 阿里云Kubernetes容器服务上体验Knative
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 包装类对象
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 电商搜索引擎的架构设计和性能优化
  • 什么是Javascript函数节流?
  • 使用 Docker 部署 Spring Boot项目
  • 小程序测试方案初探
  • 小程序开发中的那些坑
  • ionic异常记录
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • # 职场生活之道:善于团结
  • #1014 : Trie树
  • #AngularJS#$sce.trustAsResourceUrl
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (1)bark-ml
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)springboot教学评价 毕业设计 641310
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (力扣)1314.矩阵区域和
  • (六)Hibernate的二级缓存
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (五)activiti-modeler 编辑器初步优化
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)mysql使用Navicat 导出和导入数据库
  • (转载)Linux 多线程条件变量同步
  • (转载)利用webkit抓取动态网页和链接
  • .jks文件(JAVA KeyStore)
  • .NET 4.0中的泛型协变和反变
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net core控制台应用程序初识
  • .net 反编译_.net反编译的相关问题