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部分. 做项目,就是踩坑, 一路做项目,一路踩坑,坑多不可怕 ...
随机推荐
- D3.js 之 d3-shap 简介(转)
[转] D3.js 之 d3-shap 简介 译者注 原文: 来自 D3.js 作者 Mike Bostock 的 Introducing d3-shape 译者: ssthouse 联系译者: 邮箱 ...
- HTTP状态码了解
1xx - - 消息 2xx - - 成功 3xx - - 重定向 4xx - - 请求错误 5xx - - 服务器错误 1xx-信息提示 这些状态代码表示临时的响应.客户端在收到 ...
- php写的非常简单的文件浏览器
php写的非常简单的一个文件浏览器,仅供参考. <?php /** * php文件浏览程序函数 showDir() * * $dirName 输入目录路径,默认php文件一级目录,不需输入: * ...
- 算法训练 Pollution Solution(计算几何)
问题描述 作为水污染管理部门的一名雇员,你需要监控那些被有意无意倒入河流.湖泊和海洋的污染物.你的其中一项工作就是估计污染物对不同的水生态系统(珊瑚礁.产卵地等等)造成的影响. 你计算所使用的模型已经 ...
- IDEA mybatis-generator 逆向工程
1.在maven工程中的resource中创建generatorConfig.xml 2.配置generatorConfig.xml <?xml version="1.0" ...
- Flume启动报错[ERROR - org.apache.flume.sink.hdfs. Hit max consecutive under-replication rotations (30); will not continue rolling files under this path due to under-replication解决办法(图文详解)
前期博客 Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解) 问题详情 -- ::, (SinkRunner-PollingRunner-Default ...
- Java技术列表
完整的java技术列表,可以在oracle官网找到: https://www.oracle.com/technetwork/java/javaee/tech/index.html JSR: Java ...
- SwiftMailer 发送邮件时 提示fsockopen() 被禁用
站点转移空间,发送邮件的SwiftMailer 类提示错误如下: Warning: fsockopen() has been disabled for security reasons in D:\1 ...
- ORA-14517: Subpartition of index "string.string" is in unusable state
今天碰到个ORA-03113, 原因不明. 猜测因为某些table DDL操作过后导致index unuable的case, 然后进行analyze table, 再碰到ORA-14517. 最后通 ...
- WEB视频播放器插件,总结
WEB视频播放器插件,总结 2018年07月29日 20:42:11 流光忆莲 阅读数:572更多 个人分类: 推荐文章收藏 以下是关于网页中嵌入视频播放插件的各种资料的总结 基于H5的Vedio ...