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的更多相关文章

  1. WebGL 踩坑系列-3

    WebGL 踩坑系列-3 绘制球体 在 WebGL 中绘制物体时需要的顶点是以直角坐标表示的, 当然了,gl_Position 是一个四维的向量,一般将顶点赋值给 gl_Position 时,最后一维 ...

  2. WebGL 踩坑系列-2

    需求:绘制斑点在球面上走过的路径 思路:要绘制斑点在球面上走过的路径,首先要记录上一时刻和当前时刻该斑点所在球面的位置,并且实时更新当前时刻的斑点位置和上一时刻的斑点位置. 为了方便,上一时刻斑点所在 ...

  3. jmeter踩坑系列

    1.踩坑系列一: 抓包出来有host的字段,放到jmeter里面一起请求就报错了,去掉就请求正常了 1.踩坑系列二: 从花瓶复制过去 的values 前面有空格,肉眼看起来没有

  4. python踩坑系列之导入包时下划红线及报错“No module named”问题

    python踩坑系列之导入包时下划红线及报错“No module named”问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下(fileshand ...

  5. 踩坑系列の Oracle dbms_job简单使用

    二话不说先上代码 --创建存储过程 create or replace procedure job_truncateState is begin --此处就是要定时执行的sql execute imm ...

  6. Vue踩坑系列

    前言 前端开发对于vue的使用已经越来越多,它的优点就不做介绍了, 本篇是我对vue使用过程中遇到的问题中做的一些总结,帮助大家踩坑.如果喜欢的话可以点波赞,或者关注一下,希望本文可以帮到大家!!! ...

  7. 踩坑系列:MySql only_full_group_by配置,竟导致所有应用报错?

    1. 踩坑经历 一个很平常的下午,大家都在埋头认真写bug呢,突然企业微信群里炸锅了,好多应用都出现大量的Error日志,而且都报同一个错误,就是下面这个: Caused by: com.mysql. ...

  8. 【踩坑系列】使用long类型处理金额,科学计数法导致金额转大写异常

    1. 踩坑经历 上周,一个用户反馈他创建的某个销售单无法打开,但其余销售单都可以正常打开,当时查看了生产环境的ERROR日志,发现抛了这样的异常:java.lang.NumberFormatExcep ...

  9. electron踩坑系列之一

    前言 以electron作为基础框架,已经开发两个项目了.第一个项目,我主要负责用react写页面,第二项目既负责electron部分+UI部分. 做项目,就是踩坑, 一路做项目,一路踩坑,坑多不可怕 ...

随机推荐

  1. 理解JavaScript普通函数以及箭头函数里使用的this

    this 普通函数的this 普通函数的this是由动态作用域决定,它总指向于它的直接调用者.具体可以分为以下四项: this总是指向它的直接调用者, 例如 obj.func() ,那么func()里 ...

  2. 大佬写的js生成玫瑰(来源网络)

    <!DOCTYPE html> <html> <head> <title>js html5渲染的3D玫瑰花(程序员的情人节礼物)</title&g ...

  3. P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

    题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. 输出格式: 输出一 ...

  4. php实现页面跳转的几种方式

    PHP中实现页面跳转有一下几种方式,看了几个人写的不是很条理,自己整理一下 在PHP脚本代码中实现 <?php header("location:url地址") ?> ...

  5. linux1--常用命令

    1.目录结构 2./etc:系统配置文件存放地 比如你的wsgi的配置文件,nginx 3./usr 应用程序存放地 比如你的jdk应用程序存放地 4./root 系统管理员root的家目录 4.1像 ...

  6. Qt 学习之路 2(14):对话框数据传递

    Home / Qt 学习之路 2 / Qt 学习之路 2(14):对话框数据传递 Qt 学习之路 2(14):对话框数据传递  豆子  2012年9月15日  Qt 学习之路 2  53条评论 对话框 ...

  7. N - 嘤嘤嘤 (并查集+枚举)

    Our lovely KK has a difficult Social problem. A big earthquake happened in his area. N(2≤N≤2000)N(2≤ ...

  8. PreparedStatement是如何防止SQL注入的?

    为什么在Java中PreparedStatement能够有效防止SQL注入?这可能是每个Java程序员思考过的问题. 首先我们来看下直观的现象(注:需要提前打开mysql的SQL文日志) 1. 不使用 ...

  9. 使用vlookup函数下拉全部相同解决

    菜单“公式”-“计算选项”改为自动 ref: https://zhidao.baidu.com/question/561971299094821004.html

  10. Ancoda 下的python多版本共存

    Ancoda 下的python多版本共存 virtualenv python 多版本共存 Pip, Virtualenv 和Fabric 被称为python 的三大神器,Pip 是包管理工具,Virt ...