WebGL 踩坑系列-3
WebGL 踩坑系列-3
绘制球体
在 WebGL 中绘制物体时需要的顶点是以直角坐标表示的,
当然了,gl_Position 是一个四维的向量,一般将顶点赋值给 gl_Position 时,最后一维会设为 1,
gl_Position = uMVPMatrix * vec4(aVertexPosition, 1.0);
这个时候的 aVertexPosition 三维向量就代表了顶点的直角坐标。
如果我们计算出球面上的顶点,并以直角坐标的形式传入着色器中,用合适的方式绘制,就能画出球面了。
但是,绘制球体需要用到顶点,如果直接用直角坐标,并不好计算,
这时候需要用到球坐标系将球面上的各个顶点表示出来,然后再将球坐标表示成直角坐标。
/**
* 假设球心即为原点,将球面坐标系转换成平面直角坐标系
* @param theta 球心到顶点的连线与 Z 轴正方向的夹角为 theta,范围是 [0, 180]
* @param beta 球心到顶点的连线在 xoy 平面上的投影与 X 轴正方向的夹角为 beta,范围是 [0, 360]
* @param r 球半径
* @return 顶点的坐标,用三维数组表示
*/
function calcVertex(theta, beta, r) {
var st = Math.sin(Math.PI * theta / 180);
var ct = Math.cos(Math.PI * theta / 180);
var sb = Math.sin(Math.PI * beta / 180);
var cb = Math.cos(Math.PI * beta / 180);
var x = r * st * cb;
var y = r * st * sb;
var z = r * ct;
return [x, y, z];
}
这个 calcVertex 函数就够把特定角度和半径的球坐标转换成相应的直角坐标了。
现在只需要从 0 - 180 遍历 theta,0 - 360 遍历 beta 角,就可以得到球面上的所有顶点了。
var n = 48;
var vetices = [];
var r = 1;
for( var j = 0; j < n; j++ ) {
for( var i = 0; i < n: i++ ) {
vertices.push.apply( vertices, calcVertex( i * 180 / n, j * 360 / n, r ) );
// 或者用数组的 concat 方法,效果是一样的,不过据说 concat 方法更高效
// vertices = vertices.concat( calcVertex( i * 180 / n, j * 360 / n, r ) );
}
}
接下来把得到的顶点传入 gl 的缓冲区中,
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
如果只是利用这些顶点,还不能画出球面,借助索引缓冲区可以实现:
var index = [];
for ( j = 0; j < n; j++ ) {
for ( i = 0; i < n+1; i++ ) {
index.push(
i + j * (n+1), // 0
i+1 + j * (n+1), // 1
i+1 + (j+1) * (n+1) // n+1
);
index.push(
i + j * (n+1), // 0
i+1 + (j+1) * (n+1) // n+1
i + (j+1) * (n+1) // n
);
}
}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);
最后就能在 canvas 画布上画出球面了,n 越大,球面越精细,画出的球越圆滑。
ThreeJS 绘制球形
由于有导入模型的需求,开始接触 ThreeJS,用这个框架只需要调用 SphereGeometry 的 API 生成一个球,最后把球添加到场景中并进行渲染即可。
sphere = new THREE.Mesh(
new THREE.SphereGeometry(4, 36, 36),
new THREE.MeshPhongMaterial( {
opacity: 0.65,
transparent: true,
color: 0xeeeeee
} )
);
scene.add(sphere);
总结
尽管 ThreeJS 对底层的 WebGL 封装的很好,但是我只需要导入 OBJ 格式的模型就行了,ThreeJS 很强大,用起来也很方便。
而要从 WebGL 写的话,还需要去了解 GLSL 着色器语言,自己编写着色器代码,繁琐很多。
WebGL 踩坑系列-3的更多相关文章
- WebGL 踩坑系列-1
WebGL 中的一些选项WebGL 中开启颜色混合(透明效果) gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALP ...
- 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部分. 做项目,就是踩坑, 一路做项目,一路踩坑,坑多不可怕 ...
随机推荐
- winform ComBox绑定数据
初始化数据: List<KeyValuePair<string, string>> list: ComBox1.ValueMember = "Key";Co ...
- JVM各区域的用途
程序计数器 用于给字节码解释器来选取吓一跳需要执行的字节码指令.每个线程有一个独立的程序计数器去,且各个线程之间互不影响.如果线程正在执行一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令 ...
- 使用jenkins来跑docker image的惨痛经历
记录一下我使用jenkins来跑docker container的艰辛路程吧,是照着jenkins官网的[文档](https://jenkins.io/doc/tutorials/build-a-ja ...
- 51nod1453(排列组合)
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1453 题意: 中文题诶~ 思路: 因为最后一个球总是在编号比 ...
- 用 LVS 搭建一个负载均衡集群(转)
http://blog.jobbole.com/87503/ 第一篇:<如何生成每秒百万级别的 HTTP 请求?> 第二篇:<为最佳性能调优 Nginx> 第三篇:<用 ...
- python 编辑器PyCharm
1.安装与激活 (1)首先去官网下载安装(这个没什么操作) (2)激活,打开编辑器,然后选择这个,进入 http://idea.lanyus.com/ 后按照提示的修改文件内容,安装激活就完成了 2 ...
- CF580C Kefa and Park dfs
Kefa decided to celebrate his first big salary by going to the restaurant. He lives by an unusual pa ...
- 牛客寒假算法基础集训营4 G Applese 的毒气炸弹
链接:https://ac.nowcoder.com/acm/contest/330/G来源:牛客网 众所周知,Applese 是个很强的选手,它的化学一定很好. 今天他又AK了一套题觉得很无聊,于是 ...
- Web安全工程师(进阶)课程表
01-SQL注入漏洞原理与利用 预备知识: 了解HTTP协议,了解常见的数据库.脚本语言.中间件.具备基本的编程语言基础. 授课大纲: 第一章:SQL注入基础 1.1 Web应用架构分析1.2 SQL ...
- python 中文路径问题
Python直接读取中文路径的文件时失败,可做如下处理: inpath = 'D:/work/yuanxx/在线导航/驾车导航/walk_log/20130619_172355.txt' uipath ...