WebGL模型视图投影矩阵

news2025/5/24 3:11:05

WebGL透视投影_山楂树の的博客-CSDN博客中的PerspectiveView代码一个问题是,我们用了一大段枯燥的代码来定义所有顶点和颜色的数据。示例中只有6个三角形,我们还可以手动管理这些数据,但是如果三角形的数量进一步增加的话,那可真就是一团糟了。幸运的是,对这个问题,确实还有更高效的方法。

仔细观察下图,你会发现左右两组三角形的大小、位置、颜色都是对应的。如果在虚线标识处也有这样3个三角形,那么将它们向X轴正方向平移0.75单位就可以得到右侧的三角形,向X轴负方向平移0.75单位就可以得到左侧的三角形。

利用这一点,我们只需按照下面的步骤,就能获得WebGL透视投影_山楂树の的博客-CSDN博客的效果了: 

1.在虚线处,即沿着Z轴准备3个三角形的顶点数据。

2.将其沿X轴正方向(以原始位置为基准)平移0.75单位,绘制这些三角形。

3.将其沿X轴负方向(以原始位置为基准)平移0.75单位,绘制这些三角形。

示例程序PerspectiveView_mvp就尝试这样做。 

PerspectiveView程序使用投影矩阵定义可视空间,使用视图矩阵定义观察者,而PerspectiveView_mvp程序又加入了模型矩阵,用来对三角形进行变换。

矩阵推导

我们有必要复习一下矩阵变换。请看之前编写的WebGL 视图矩阵、模型视图矩阵_山楂树の的博客-CSDN博客程序LookAtRotatedTriangles,该程序允许观察者从自定义的位置观察旋转后的三角形。等式1描述了三角形顶点的变换过程。

<视图矩阵>×<模型矩阵>×<顶点坐标>

后来的LookAtTriangles_ViewVolume程序(该程序修复了三角形的一个角被切掉的错误)使用等式2来计算最终的顶点坐标,其中投影矩阵有可能是正射投影矩阵或透视投影矩阵。 

<投影矩阵>×<视图矩阵>×<顶点坐标>

可以从上述两式推断出等式3

<投影矩阵>×<视图矩阵>×<模型矩阵>×<顶点坐标> 

等式3表示,在WebGL中,你可以使用投影矩阵、视图矩阵、模型矩阵这3种矩阵计算出最终的顶点坐标(即顶点在规范立方体中的坐标)。

如果投影矩阵为单位阵,那么等式3等式1就完全相同了;同样,如果模型矩阵为单位阵,那么等式3等式2就完全相同了。单位阵就像乘法中的1一样,它乘以任意一个矩阵,或者任意一个矩阵乘以它,得到的结果还是这个矩阵(程序中不设置投影矩阵所需的任一参数,默认参数所计算得到的矩阵可理解为1)。 

模型视图投影矩阵示例代码(PerspectiveView_mvp

var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'attribute vec4 a_Color;\n' +
  'uniform mat4 u_ModelMatrix;\n' +
  'uniform mat4 u_ViewMatrix;\n' +
  'uniform mat4 u_ProjMatrix;\n' +
  'varying vec4 v_Color;\n' +
  'void main() {\n' +
  '  gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
  '  v_Color = a_Color;\n' +
  '}\n';

var FSHADER_SOURCE =
  '#ifdef GL_ES\n' +
  'precision mediump float;\n' +
  '#endif\n' +
  'varying vec4 v_Color;\n' +
  'void main() {\n' +
  '  gl_FragColor = v_Color;\n' +
  '}\n';

function main() {
  var canvas = document.getElementById('webgl');
  var gl = getWebGLContext(canvas);
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) return
  // 设置顶点坐标和颜色(蓝色三角形在前面)
  var n = initVertexBuffers(gl);
  gl.clearColor(0, 0, 0, 1);
  // 获取u_ModelMatrix、u_ViewMatrix和u_ProjectMatrix的存储位置
  var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
  var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');

  var modelMatrix = new Matrix4(); // 模型矩阵
  var viewMatrix = new Matrix4();  // 视图矩阵
  var projMatrix = new Matrix4();  // 投影矩阵

  // 计算视图矩阵和投影矩阵
  modelMatrix.setTranslate(0.75, 0, 0);  // 沿正x轴平移0.75个单位
  viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0); // 视点、观察点、正方向
  projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100); // 视角、近截面宽高比、near、far
  // 将模型、视图和投影矩阵分别传递给统一变量
  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
  gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);

  gl.clear(gl.COLOR_BUFFER_BIT); 
  gl.drawArrays(gl.TRIANGLES, 0, n); // 绘制右侧三角形

  // 为另一对三角形准备模型矩阵
  modelMatrix.setTranslate(-0.75, 0, 0); // 沿负x轴平移0.75个单位
  // 仅修改模型矩阵
  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  gl.drawArrays(gl.TRIANGLES, 0, n);   // 绘制左侧三角形
}

function initVertexBuffers(gl) {
  var verticesColors = new Float32Array([
    // 顶点坐标和颜色
     0.0,  1.0,  -4.0,  0.4,  1.0,  0.4, // 后面的绿色
    -0.5, -1.0,  -4.0,  0.4,  1.0,  0.4,
     0.5, -1.0,  -4.0,  1.0,  0.4,  0.4, 
     0.0,  1.0,  -2.0,  1.0,  1.0,  0.4, // 中间的黄色
    -0.5, -1.0,  -2.0,  1.0,  1.0,  0.4,
     0.5, -1.0,  -2.0,  1.0,  0.4,  0.4, 
     0.0,  1.0,   0.0,  0.4,  0.4,  1.0,  // 前面的蓝色
    -0.5, -1.0,   0.0,  0.4,  0.4,  1.0,
     0.5, -1.0,   0.0,  1.0,  0.4,  0.4, 
  ]);
  var n = 9;
  var vertexColorbuffer = gl.createBuffer();  
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  gl.enableVertexAttribArray(a_Position);
  var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  gl.enableVertexAttribArray(a_Color);
  return n;
}

代码详解 

顶点着色器第9行实现了等式3

main()函数调用initVertexBuffers()函数(第27行),定义将要传给缓冲区对象的三角形顶点数据(第58行)。我们只定义了3个三角形,其中心都在Z轴上。而在PerspectiveView.js中,我们在Z轴两侧共定义了6个三角形。前面说过,这是因为这3个三角形将与平移变换结合使用。 

接着,我们获取了顶点着色器中u_ModelMatrix变量的存储地址(第30行),然后新建了模型矩阵modelMatrix对象(第34行),并根据参数将其计算出来(第39行)。此时,该模型矩阵会将三角形向X轴正方向平移0.75单位。

 除了计算模型矩阵(第39行),计算视图矩阵和投影矩阵的过程与PerspectiveView.js中一样。模型矩阵被传给u_ModelMatrix(第43行)并进行绘制,绘制了Z轴右侧的3个三角形(第48行)。

下面以相似的方式来绘制左侧的三角形:首先重新计算模型矩阵(第51行),使之将初始的三角形沿X轴负方向平移0.75单位。算出新的模型矩阵后,传给着色器,再调用gl.drawArrays()进行绘制,就画出了左侧的三角形。视图矩阵和投影矩阵不需要变化,不需要管它们。

如你所见,程序只使用了一套数据(3个三角形的顶点和颜色信息)就画出了两套图形(6个三角形)。这样做虽然减少了顶点的个数,但是增加了调用gl.drawArrays()的次数。哪一种方法更高效,或者如何在这两者之间平衡,依赖于程序本身和WebGL的实现。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1010733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何评估RPA需求?

在当今数字化的商业环境中,RPA(Robotic Process Automation,即机器人流程自动化)的需求日益增长,因为它能够帮助企业提高效率、减少错误、节省成本,以及提高员工满意度。然而,尽管RPA的潜力巨大…

秋目阅读企划 —— 小K图书推荐(文末赠书)

目录 1、写在前面2、深入理解Java高并发编程3、信息学奥赛一本通关4、文末赠书 1、写在前面 不知道大家有没有和我一样的感受,在发现一本好书的时候,非常想入手,但是奈何囊中羞涩…苦等1024,现在不用等啦~清华大学出版社的秋日阅读…

短剧解说小程序搭建,短剧解说小程序源码

短剧解说小程序搭建,短剧解说小程序源码 可定制开发小程序,H5,APP等系统 有需要可定制可出源码,这个是啥你懂的(VVVVVVVVVVV):二五四九七八九零五九 需要源码或搭建可看上面的数字信息 短剧解说小程序搭建 小程序使用…

第37章_瑞萨MCU零基础入门系列教程之DAC数模转换模块

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…

【WFA】【Enhanced open】CT_OWE_DHgroup_STA_NoAssociation-AllGroupsRejected_10338_1

测试报告如下: Fail的关键log: 当连接到ap失败时,驱动程序将尝试连接到ap。如果ap仅支持Group 20,并且sta支持Group 19、20。sta将首先尝试Group 19,ap将通过状态代码77拒绝它。然后驱动程序将尝试连接Group 19的ap,仍然达到最大重试次数。那么sta将尝试第Group 20 。 …

重磅!文晔以38亿美元收购富昌电子 | 百能云芯

文晔微电子股份有限公司(文晔科技)于9月14日正式宣布已完成对富昌电子公司(Future Electronics Inc.)100%股权的收购,该交易以全现金方式完成,总交易价值高达38亿美元。 文晔科技的董事长兼首席执行官郑家强…

【案例+操作+演示】20分钟带你入门Pandas,掌握数据分析科学模块,附带上百个案例练习题【含答案】

二十分钟入门pandas,学不会私信教学! 有需要pyecharts资源的可以点击文章上面下载!!! 需要本项目运行源码可以点击资源进行下载 资源 #coding:utf8 %matplotlib inline这个一篇针对pandas新手的简短入门&#xff0…

Anaconda安装和配置 ---- 详细到家

安装 1.打开Anaconda官网,选择对应版本,下载到对应目录即可 或者进入: Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.双击打开.exe文件,然后点击next ; 3.点击agree 4.点击just me,然后next; 5.在Choose Ins…

C++QT day7

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 #include <iostream>using namespace std;template<typename T> class my_vector {int size;//可存储的容量大小int num;//当前存储的元素个数T* data;//存储数据的空间地址public://无参构造…

C++下基于粒子群算法解决TSP问题

粒子群优化算法求解TSP旅行商问题C&#xff08;2020.11.12&#xff09;_jing_zhong的博客-CSDN博客 混合粒子群算法&#xff08;PSO&#xff09;&#xff1a;C实现TSP问题 - 知乎 (zhihu.com) 一、原理 又是一个猜答案的算法&#xff0c;和遗传算法比较像&#xff0c;也是设…

小米手机安装面具教程(Xiaomi手机获取root权限)

文章目录 1.Magisk中文网&#xff1a;2.某呼&#xff1a;3.最后一步打开cmd命令行输入的时候:4.Flash Boot 通包-Magisk&#xff08;Flash Boot通刷包&#xff09;5.小米Rom下载&#xff08;官方刷机包&#xff09;6.Magisk最新版本国内源下载 1.Magisk中文网&#xff1a; htt…

深入解析 Nginx 代理配置:从 server 块到上游服务器的全面指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

XSS跨站脚本攻击

XSS全称&#xff08;Cross Site Scripting&#xff09;跨站脚本攻击,XSS属于客户端攻击&#xff0c;受害者最终是用户&#xff0c;在网页中嵌入客户端恶意脚本代码&#xff0c;最常用javascript语言。&#xff08;注意&#xff1a;叠成样式表CSS已经被占用所以叫XSS&#xff09…

(vue2).sync修饰符、ref和$refs、$nextTick、自定义指令、插槽

.sync修饰符 实现子组件和父组件数据的双向绑定 &#xff0c;简化代码 prop属性名&#xff0c;可以自定义&#xff0c;非固定value 本质&#xff1a;属性名和update&#xff1a;属性名的合写 <BaseDialog :value"isShow" update"isShow$event"> /…

朋友圈大佬都去读研了,这份备考书单我码住了(文末赠书)

朋友圈大佬都去读研了&#xff0c;这份备考书单我码住了 1、《数据结构与算法分析》2、《计算机网络&#xff1a;自顶向下方法》3、《现代操作系统》4、《深入理解计算机系统》5、《概率论基础教程&#xff08;原书第10版》6、《线性代数&#xff08;原书第10版&#xff09;》7…

猫爪插件-官网下载方法

一、猫抓 github 二、下载 三、安装 谷歌浏览器&#xff0c;打开插件页面&#xff0c;打开开发者模式&#xff0c;将插件拖入浏览器安装。

数学实验-素数(Mathematica实现)

一、实验名称&#xff1a;素数 二、实验环境&#xff1a;Mathematica 10.3软件 三、实验目的&#xff1a;本实验将探讨素数的规律&#xff0c;研究素数的判别、最大的素数、构成生成素数的公式和素数的分布&#xff0c;并学会求解某些范围内的素数。 四、实验内容、步骤以及…

Maven仓库Nexus安装部署

Nexus是半开源软件&#xff0c;用于支持Apache Maven的在线仓库&#xff0c;Maven在CI/CD领域中&#xff0c;支持Java工程编译、打包、发布&#xff0c;而Maven发布的目的地是Nexus中央仓库。Nexus也提供商业版本&#xff0c;商业版本支持高可用、企业级统一认证与登录以及其他…

MobaXterm工具软件使用介绍

大家好&#xff0c;我是虎哥&#xff0c;最近由于大部分嵌入式的系统都切换到了ubuntu20.04及更高版本的系统&#xff0c;导致我自己使用的Xshell也需要从5升级到7&#xff0c;但是Xshell7尽然开始收费了&#xff0c;网上也没有什么好用的破解版本&#xff0c;索性我就准备找个…

2023年浦东新区数字化安全风险智慧管控技能比武初赛-技能题一

目录 二、技能题 2.1 MD5===MD5 三、业*&&&务**&&联&&&*&&系 二、技能题 2.1 MD5===MD5