WebGL 踩坑系列-1
WebGL 中的一些选项
WebGL 中开启颜色混合(透明效果)
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
设置遮挡剔除有效。生成三角形时,沿着逆时针方向的那面会被生成出来,而另一面就不会生成出来。
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
观察球面的效果:
当设置透明效果却不开启遮挡剔除的时候,用 web GL 生成球面,在球外观察球面时就会看到一些奇怪的角。
第二个球就很明显的有一些不同的部分。
在 web GL 中使用矩阵
可以利用矩阵的平移、旋转、缩放实现物体的各种动作。
我在最开始使用 Web GL 绘图的时候,球面上的点都是利用循环得到,但是由于有缩放球面的需求,所以最开始的做法是
1. 创建缓冲区时用的 gl.DYNAMIC_DRAW
2. 当要缩放球面时,重新计算顶点
3. 用 gl.updateBufferData 函数更新定点数据
当缩放的时候就能明显看到画面撕裂,帧率下降。
可能的原因是:
1. 每次重新计算都要使用大量的计算资源,若帧率为 60,那么每秒要计算上千个顶点,如果球面较精细,那么需要计算的顶点数更多。
2. 并且每次计算之后都要将这些顶点传入到 GPU 中,可能会占用一部分的传输带宽
正常的做法是用坐标变换矩阵,将变换后的矩阵通过 gl.uniformMatrix4fv 传入到着色器,就可以轻松的实现平移旋转和缩放。并且不会造成性能严重下降。
但是矩阵的乘法与普通的数乘有所差别,矩阵的乘法一般不满足交换律。
若 pMatrix 表示透视矩阵,vMatrix 表示视图矩阵,mMatrix 表示模型矩阵,aVertex 表示传入的顶点,那么一般的乘式是
gl_Position = pMatrix * vMatrix * mMatrix * aVertex;
如果矩阵的顺序不同,可能最后得到的图形也就不同。
对矩阵先进行旋转操作,再进行平移操作。缩放操作的顺序一般没有影响。
但我在使用 gl-Matrix.js 时,对一个矩阵先进行旋转,再进行平移操作:
mat4.identity(this.mMatrix); mat4.fromRotation(this.mMatrix, angle[1] * Math.PI*2, [0, 0, 1]);
mat4.rotate(this.mMatrix, this.mMatrix, angle[0] * Math.PI, [0, 1, 0]);
mat4.translate(this.mMatrix, this.mMatrix, pos); mat4.multiply(mvpMatrix, pvMatrix, this.mMatrix);
gl.uniformMatrix4fv(uniforms.pmv_matrix, false, mvpMatrix);
和将旋转操作和平移操作放在两个矩阵中进行得到的结果并不相同。
mat4.identity(this.mMatrix); mat4.fromRotation(this.rMatrix, angle[1] * Math.PI*2, [0, 0, 1]);
mat4.rotate(this.rMatrix, this.rMatrix, angle[0] * Math.PI, [0, 1, 0]);
mat4.translate(this.mMatrix, this.mMatrix, pos);
mat4.mul(this.mMatrix, this.mMatrix, this.rMatrix); mat4.multiply(mvpMatrix, pvMatrix, this.mMatrix);
gl.uniformMatrix4fv(uniforms.pmv_matrix, false, mvpMatrix);
注意这里用 pvMatrix 乘 mMatrix 之前先用 mMatrix 乘了一个附加矩阵 rMatrix。
具体的原因并不清楚,但是第二个操作实现的图像符合我的需求。
=========================
这几天又重新测试了下代码,发现上面的旋转平移操作的矩阵还是有些问题,
具体问题在于经过旋转平移后的面上反的,以下矩阵操作可以方便的做到旋转平移,并且得到的面上正的
mat4.fromZRotation(this.rMatrix, this.beta); // 绕 Z 轴旋转 beta 角
mat4.rotateY(this.rMatrix, this.rMatrix, this.theta); // 再绕 Y 轴旋转 theta 角
mat4.fromRotationTranslation(this.mMatrix, this.rMatrix, pos);
mat4.rotateZ(this.mMatrix, this.mMatrix, this.beta);
mat4.rotateY(this.mMatrix, this.mMatrix, this.theta);
最后得到的面就是我想要的
完整的代码可以在我的 GitHub 上查看。
WebGL 踩坑系列-1的更多相关文章
- WebGL 踩坑系列-3
WebGL 踩坑系列-3 绘制球体 在 WebGL 中绘制物体时需要的顶点是以直角坐标表示的, 当然了,gl_Position 是一个四维的向量,一般将顶点赋值给 gl_Position 时,最后一维 ...
- WebGL 踩坑系列-2
需求:绘制斑点在球面上走过的路径 思路:要绘制斑点在球面上走过的路径,首先要记录上一时刻和当前时刻该斑点所在球面的位置,并且实时更新当前时刻的斑点位置和上一时刻的斑点位置. 为了方便,上一时刻斑点所在 ...
- jmeter踩坑系列
1.踩坑系列一: 抓包出来有host的字段,放到jmeter里面一起请求就报错了,去掉就请求正常了 1.踩坑系列二: 从花瓶复制过去 的values 前面有空格,肉眼看起来没有
- python踩坑系列之导入包时下划红线及报错“No module named”问题
python踩坑系列之导入包时下划红线及报错“No module named”问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下(fileshand ...
- 踩坑系列の Oracle dbms_job简单使用
二话不说先上代码 --创建存储过程 create or replace procedure job_truncateState is begin --此处就是要定时执行的sql execute imm ...
- Vue踩坑系列
前言 前端开发对于vue的使用已经越来越多,它的优点就不做介绍了, 本篇是我对vue使用过程中遇到的问题中做的一些总结,帮助大家踩坑.如果喜欢的话可以点波赞,或者关注一下,希望本文可以帮到大家!!! ...
- 踩坑系列:MySql only_full_group_by配置,竟导致所有应用报错?
1. 踩坑经历 一个很平常的下午,大家都在埋头认真写bug呢,突然企业微信群里炸锅了,好多应用都出现大量的Error日志,而且都报同一个错误,就是下面这个: Caused by: com.mysql. ...
- 【踩坑系列】使用long类型处理金额,科学计数法导致金额转大写异常
1. 踩坑经历 上周,一个用户反馈他创建的某个销售单无法打开,但其余销售单都可以正常打开,当时查看了生产环境的ERROR日志,发现抛了这样的异常:java.lang.NumberFormatExcep ...
- electron踩坑系列之一
前言 以electron作为基础框架,已经开发两个项目了.第一个项目,我主要负责用react写页面,第二项目既负责electron部分+UI部分. 做项目,就是踩坑, 一路做项目,一路踩坑,坑多不可怕 ...
随机推荐
- netty下载源码并导入idea
netty源码导入eclipse会有一些兼容性问题,网上有解决方案,官方推荐idea,故此用idea. 拷贝git地址:https://github.com/netty/netty.git 使用git ...
- Android emulator中C代码的调试——gdb/gdbservers时遇到的坑
版权声明:本文为博主原创文章,未经博主允许不得转载. 先写个helloworld吧,在Android源码树中创建文件夹external/helloworld,加入文件: // helloworld.c ...
- day01.1-计算机体系与数据描述
一. 指令执行过程 二. 计算机体系架构 其中,ROM所存数据较为 ...
- Python中__call__的用法
概念: Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的.换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符. 示例: 所 ...
- mybatis 批量update两种方法对比
<!-- 这次用resultmap接收输出结果 --> <select id="findByName" parameterType="string&qu ...
- cmake相关问题
一.cmake升级 在ubuntu 16.04下面把cmake 由 3.5.1升级到 3.11,具体的流程如下所述. (1) sudo apt-get install build-essential ...
- Boost lockfree deque 生产者与消费者多对多线程应用
boost库中有一个boost::lockfree::queue类型的 队列,对于一般的需要队列的程序,其效率都算不错的了,下面使用一个用例来说明. 程序是一个典型的生产者与消费者的关系,都可以使用多 ...
- 「模拟赛20180406」膜树 prufer编码+概率
题目描述 给定一个完全图,保证\(w_{u,v}=w_{v,u}\)且\(w_{u,u}=0\),等概率选取一个随机生成树,对于每一对\((u,v)\),求\(dis(u,v)\)的期望值对\(998 ...
- 文件上传之form表单篇
form表单上传文件 作为本系列的最后一篇,也是楼主知道的第三种文件上传的方式--隆重推出Form表单 这是最传统的上传文件,提交数据的方式 Html: <form action="/ ...
- 使用Tensorflow object detection API——训练模型(Window10系统)
[数据标注处理] 1.先将下载好的图片训练数据放在models-master/research/images文件夹下,并分别为训练数据和测试数据创建train.test两个文件夹.文件夹目录如下 2. ...