三维视图正射投影矩阵

  • 1.demo效果
  • 2.相关知识点
    • 2.1 正射投影
    • 2.2 Matrix4.setOrtho()函数
  • 3. demo代码

1.demo效果

如上,通过上下键调整正投影矩阵参数far的值,通过左右键调整正投影矩阵near的值,重新设置可视空间,实现页面中的三角形消失与复现

2.相关知识点

2.1 正射投影

对于人类而言,只能看到眼前的东西,这就是我们所说的可视范围,在WebGL中同样有可视范围,它包括水平视角、垂直视角和可视深度,我们根据这三个要素定义了 可视空间 ,对于不在可视空间的图形,通常不会将它绘制出来,因为绘制可视范围外的图形没有意义,同时可以降低不必要的内存开销。在三维世界中可视范围目前常用的可视空间有两类:

  • 长方体可视空间,也成盒装空间,由 正射投影 产生
  • 四棱锥/金字塔可视空间,由 透视投影 产生

透视投影产生的三维空间看上去更有深度感,更加自然,因为我们平时观察真实世界也是透视投影,在大多数情况下我们使用透视投影,也有一些情况,比如比较两个原子的模型或者在建筑平面图形等方面希望物体的大小不受所在位置影响,这时我们会使用正射投影。
接下来先介绍一下正射投影的盒状可视空间工作原理

如上图,我们把空间坐标 X轴、Y轴、Z轴的交汇点即原点设为视点位置,距离视点为距离为near的面我们称为近裁剪面,距离视点为距离为far的面我们称为远裁剪面,以Z轴与近裁剪面的交汇点为原点,距离这个点距离分别为top、bottom、left、right的面称为上边界、下边界、左边界、右边界,由上述六个面合成的立方体我们称为 可视空间 ,即上图中绿色立方体所占的空间。在可视空间内的物体可以观察到,可视空间外的物体观察不到。

2.2 Matrix4.setOrtho()函数

cuon-matrix.js 提供的 Matrix4.setOrtho() 函数,该函数用来设置 正射投影矩阵,定义 盒状可视空间

函数功能:根据参数top、bottom、left、right、near、far计算正射投影矩阵,将其存储在Matrix4中
-----------------------------------------------------------------------------------
调用示例:Matrix4.setOrtho(left, right, bottom, top, near, far)
-----------------------------------------------------------------------------------
参数      left, right     指定可视空间的左边界和右边界bottom, top       指定可视空间的下边界和上边界near, far     指定近裁剪面和远裁剪面的位置,即可视空间的近边界和远边界
-----------------------------------------------------------------------------------
返回值     无

3. demo代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title></title>
</head><body><!--通过canvas标签创建一个800px*800px大小的画布--><canvas id="webgl" width="800" height="800"></canvas><p id="nearFar" style="position: absolute;left: 60px;top: 100px; color: aliceblue;">near和far值显示在这里</p><script type="text/javascript" src="./lib/cuon-matrix.js"></script><script>//顶点着色器var VSHADER_SOURCE = '' +'attribute vec4 a_Position;\n' + //声明attribute变量a_Position,用来存放顶点位置信息'attribute vec4 a_Color;\n' + //声明attribute变量a_Color,用来存放顶点颜色信息'uniform mat4 u_ProjMatrix;\n' + //声明uniform变量u_ProjMatrix,用来存放正射投影矩阵'varying vec4 v_Color;\n' + //声明varying变量v_Color,用来向片元着色器传值顶点颜色信息'void main(){\n' +'  gl_Position = u_ProjMatrix * a_Position;\n' + //将正射投影矩阵与顶点坐标相乘赋值给顶点着色器内置变量gl_Position'  v_Color = a_Color;\n' + //将顶点颜色信息传给片元着色器,'}\n';//片元着色器var FSHADER_SOURCE = '' +'#ifdef GL_ES\n' +' precision mediump float;\n' + // 设置精度'#endif\n' +'varying vec4 v_Color;\n' + //声明varying变量v_Color,用来接收顶点着色器传送的片元颜色信息'void main(){\n' +//将varying变量v_Color接收的颜色信息赋值给内置变量gl_FragColor' gl_FragColor = v_Color;\n' +'}\n';//初始化着色器函数function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE) {//创建顶点着色器对象var vertexShader = gl.createShader(gl.VERTEX_SHADER);//创建片元着色器对象var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);//引入顶点、片元着色器源代码gl.shaderSource(vertexShader, VSHADER_SOURCE);gl.shaderSource(fragmentShader, FSHADER_SOURCE);//编译顶点、片元着色器gl.compileShader(vertexShader);gl.compileShader(fragmentShader);//创建程序对象programvar program = gl.createProgram();//附着顶点着色器和片元着色器到programgl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);//链接programgl.linkProgram(program);//使用programgl.useProgram(program);gl.program = program//返回程序program对象return program;}function init() {//通过getElementById()方法获取canvas画布var canvas = document.getElementById('webgl');//通过方法getContext()获取WebGL上下文var gl = canvas.getContext('webgl');//初始化着色器if (!initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('初始化着色器失败');return;}// 设置canvas的背景色gl.clearColor(0.0, 0.0, 0.0, 1.0);//清空canvasgl.clear(gl.COLOR_BUFFER_BIT);//初始化顶点坐标和顶点颜色var n = initVertexBuffers(gl)//通过getElementById()方法获取canvas画布var nfElement = document.getElementById('nearFar');//创建设置正射投影矩阵,并传给uniform变量u_ProjMatrixvar u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix') //获取顶点着色器uniform变量u_ProjMatrix的存储地址    var projMatrix = new Matrix4() //创建正射投影矩阵     projMatrix.setOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 0.5) //设置正射投影矩阵     gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements) //将正射投影矩阵传给顶点着色器uniform变量u_ProjMatrix//绘制三角形gl.drawArrays(gl.TRIANGLES, 0, n)//注册上下左右键盘按下事件document.onkeydown = function (ev) {keydown(ev, gl, n, u_ProjMatrix, projMatrix, nfElement)}}//视点与远、近裁剪面的距离var g_near = 0.0,g_far = 0.5//键盘按下处理函数function keydown(ev, gl, n, u_ProjMatrix, projMatrix, nfElement) {if (ev.keyCode == 38) { //上键g_far += 0.01} else if (ev.keyCode == 40) { //下键g_far -= 0.01} else if (ev.keyCode == 37) { //左键g_near -= 0.01} else if (ev.keyCode == 39) { //右键g_near += 0.01} else {return}draw(gl, n, u_ProjMatrix, projMatrix, nfElement)}//绘图function draw(gl, n, u_ProjMatrix, projMatrix, nfElement) {//设置正投影矩阵near和far值projMatrix.setOrtho(-1.0, 1.0, -1.0, 1.0, g_near, g_far)//将正投影矩阵传给顶点着色器uniform变量u_ProjMatrixgl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements)//清除<canvas>gl.clear(gl.COLOR_BUFFER_BIT)nfElement.innerHTML = 'near:' + Math.round(g_near * 100) / 100 + ', far:' + Math.round(g_far * 100) / 100//绘图gl.drawArrays(gl.TRIANGLES, 0, n)}//初始化顶点坐标和顶点颜色function initVertexBuffers(gl) {var verticesColors = new Float32Array([//最后面的三角形0.0, 0.5, -0.4, 0.4, 1.0, 0.4,-0.5, -0.5, -0.4, 0.4, 1.0, 0.4,0.5, -0.5, -0.4, 1.0, 0.4, 0.4,//中间的三角形0.5, 0.4, -0.2, 1.0, 0.4, 0.4,-0.5, 0.4, -0.2, 1.0, 1.0, 0.4,0.0, -0.6, -0.2, 1.0, 1.0, 0.4,//最前面的三角形0.0, 0.5, 0.0, 0.4, 0.4, 1.0,-0.5, -0.5, 0.0, 0.4, 0.4, 1.0,0.5, -0.5, 0.0, 1.0, 0.4, 0.4,]);//创建缓冲区对象var vertexColorBuffer = gl.createBuffer();if (!vertexColorBuffer) {console.log('创建缓冲区对象失败!')return -1}//将顶点坐标和顶点颜色信息写入缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer)gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW)//获取类型化数组中每个元素的大小var FSIZE = verticesColors.BYTES_PER_ELEMENT//获取顶点着色器attribute变量a_Position的存储地址, 分配缓存并开启var a_Position = gl.getAttribLocation(gl.program, 'a_Position');gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0)gl.enableVertexAttribArray(a_Position)//获取顶点着色器attribute变量a_Color(顶点颜色信息)的存储地址, 分配缓存并开启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)// 解绑缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, null);return verticesColors.length / 6}init()</script>
</body></html>

WebGL入门(十九)-三维视图通过调整正射投影矩阵/盒状可视空间实现三角形的显示与消失相关推荐

  1. WebGL入门(十六)-三维视图模型原理,视点、视线、观察点、上方向

    三维视图模型原理 1.demo效果 2.相关知识点 2.1 视点.视线.观察点.上方向 2.2 创建视图矩阵 3. demo代码 1.demo效果 如上图,这个demo中三个不同颜色的三角形展示在三维 ...

  2. QT5开发及实例学习之十九图形视图体系结构

    文章目录 一.Graphics View 框架结构的主要特点 二.Graphics View 框架结构的三元素 2.1 场景类:QGraphicsScene 类 2.2 视图类:QGraphicsVi ...

  3. [WebGL入门]十二,模型数据和顶点属性

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外.鄙人webgl研究还不够深入,一些专业词语.假设翻译有误.欢迎大家指 ...

  4. WebGL入门(十五)-使用多幅纹理/纹理叠加

    使用多幅纹理/纹理叠加 1.demo效果 2.实现要点 2.1 顶点着色器中声明varying变量v_TexCoord 2.2 片元着色器中多纹理处理 2.3 外部纹理图像加载 2.4 纹理叠加处理与 ...

  5. 安卓Andriod使用入门(十九)【网络视频播放器】

    有时侯明白人的一生当中,深刻的思念是维系自己与记忆的纽带.它维系着所有的过往.悲喜,亦指引我们深入茫茫命途.这是我们宿命的背负.但我始终甘之如饴地承受它的沉沉重量,用以平衡轻浮的生. MainActi ...

  6. 第三十九章、PyQt显示部件:OpenGL Widget部件功能简介及使用其显示图片

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 OpenGL Widget部件是一个Op ...

  7. WebGL入门(二十)-三维视图通过透视投影矩阵创建远小近大的两排三角形

    通过透视投影矩阵创建远小近大的两排三角形 1.demo效果 2.相关知识点 2.1 透视投影 2.2 Matrix4.setPerspective()函数 3. demo代码 1.demo效果 如上, ...

  8. VS2010/MFC编程入门之二十九(常用控件:列表视图控件List Control 下)

    上一节是关于列表视图控件List Control的上半部分,简单介绍了列表视图控件,其通知消息的处理和有关结构体的定义.本节继续讲解下半部分,包括列表视图控件的创建.CListCtrl类的主要成员函数 ...

  9. UWP开发入门(十九)——10分钟学会在VS2015中使用Git

    原文:UWP开发入门(十九)--10分钟学会在VS2015中使用Git 写程序必然需要版本控制,哪怕是个人项目也是必须的.我们在开发UWP APP的时候,VS2015默认提供了对微软TFS和Git的支 ...

最新文章

  1. 2019 ACM - ICPC 全国邀请赛(西安)题解(9 / 13)
  2. 用什么方式链接oracle数据库,使用cx_Oracle 连接oracle数据库的几种方式
  3. 如何解决Windows Update错误80070003
  4. 在linux中安装oracle中文包,在Linux命令行下安装Oracle 10g
  5. hdoj--1716--排列2(暴力水题)
  6. 已重置默认应用设置html,win10已重置应用默认设置一直弹怎么办_win10已重置应用默认设置老是弹出解决方法...
  7. 超给力,抛弃手动维护,一键生成数据库文档、支持多种格式!
  8. 问题 A: 百钱买百鸡问题
  9. 程序员怒了!阿里 Antd 圣诞彩蛋害我被离职了!
  10. matlab练习程序(方框模糊)
  11. sql或oracle插入数据时进行md5加密
  12. 单应性变换、仿射变换、透视变换
  13. 300.最长上升子序列
  14. 4k纸是几厘米乘几厘米_4K纸有多大 。。厘米
  15. Android Wifi密码查看器实现思路
  16. Ubuntu18.04下安装git记录
  17. Eclipse+Java+Swing+Mysql实现员工信息管理系统
  18. 推荐几个IDEA插件,Java开发者撸码神器。
  19. Http跨站点请求伪造解决方案
  20. TortoiseGit工具 修改登录用户名密码

热门文章

  1. Erlang User Conference 2010见闻(兼谈程序员职业生涯)
  2. 【专业数据】三.2020~2022年北京交通大学【控制科学与工程】专业复试线/分数线差/计划招生数/复试数/录取数/复试比例/录取率
  3. 宠物游戏代码 java
  4. 清华男的大学4年 (转)
  5. 游戏敏感词过滤的常见方式记录
  6. 给中国学生的第六封信——选择的智慧
  7. Win7下硬盘安装Ubuntu 12.04.4 LTS双系统
  8. SAP PA CO后台配置
  9. 过滤器的实际应用(编码、敏感词、压缩过滤器)
  10. Matlab2016a安装之后闪退进不去