webgl之绘图要点
3D世界是由点组成的,两个点组成一条直线,而三个点就可以组成一个三角形,通过三角形就可以组成任意形状的物体,而这种组成的物体我们称为Mesh模型,接着Mesh模型加上纹理就组成了真实的3D世界。下面我们就逐一介绍。
零、坐标系
在Three.js中,默认使用的就是右手坐标系,即将手掌伸开平行于X轴,然后屈掌使得四指平行于y轴,这时大拇指朝向与z轴相同就是右手坐标系,否则,就是左手坐标系。下面两张图的描述方法都是正确的。如下:

如上,Three.js中使用的就是右边的这个坐标系 - 右手坐标系。
一、点
在3D世界中,在建立了坐标系之后,就会通过x、y、z三个分量确定空间中的一个点。Three.js中提供了THREE.Vector3()构造函数来创建一个点,我们在源码中搜索Vector3就可以找到此构造函数的定义,如下所示:
function Vector3( x, y, z ) {
this.x = x || ;
this.y = y || ;
this.z = z || ;
}
Object.assign( Vector3.prototype, {
isVector3: true,
set: function ( x, y, z ) {
this.x = x;
this.y = y;
this.z = z;
return this;
},
setScalar: function ( scalar ) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
return this;
},
setX: function ( x ) {
this.x = x;
return this;
},
// ... 还有很多额外的方法
即首先定义了一个构造函数,然后给这个构造函数添加原型,最后,在原型上定义了一系列的方法,于是,如果我们希望获取一个点,就可以通过下面的方式:
var point = new THREE.Vector3(, , );
或者,利用实例的set方法,如下所示:
var point1 = new THREE.Vector3(, , );
二、线
两点连接即可得到一条线。而如果要在WebGL中创建一条线,需要大致如下步骤:
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial({VertexColors: true});
var p1 = new THREE.Vector3(, , -);
var p2 = new THREE.Vector3(, , );
geometry.vertices.push(p1);
geometry.vertices.push(p2);
var color1 = new THREE.Color(0x444444),
color2 = new THREE.Color(0xff00ff);
geometry.colors.push(color1, color2);
var line = new THREE.Line(geometry, material, THREE.LinePieces);
scene.add(line);
其中,我们首先创建一个Geometry(几何形状),点、线、面都是几何形状,所以画线,就要先定义一个几何形状,然后在通过THREE.LineBasicMaterial构造函数创建直线的材料,实际上,它接受一个配置对象,属性有Color(颜色)、LineWidth(宽度)、Linecap(线条两端外观)、Linejoin(两个线条连接点的外观)等等。接着,我们创建了两个点p1和p2,又push进入geometry中,vertices就是顶点的意思;然后又创建了两个颜色即两端点的颜色;再通过THREE.Line将geometry、material结合;最后添加到场景中即可。
完整代码如下:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>three.js</title>
<style>
* {
margin: ;
padding: ;
}
</style>
<script src="./three.js"></script>
</head> <body>
<script>
var scene = new THREE.Scene(); var axes = new THREE.AxesHelper();
scene.add(axes); var camera = new THREE.PerspectiveCamera(, window.innerWidth / window.innerHeight, , );
camera.position.x = ;
camera.position.y = ;
camera.position.z = ;
camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x111111);
renderer.setSize(window.innerWidth, window.innerHeight); var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial({vertexColors: true});
var p1 = new THREE.Vector3(, , -);
var p2 = new THREE.Vector3(, , );
geometry.vertices.push(p1);
geometry.vertices.push(p2);
var color1 = new THREE.Color(0x444444),
color2 = new THREE.Color(0xff00ff);
geometry.colors.push(color1, color2);
var line = new THREE.Line(geometry, material, THREE.LineSegments);
scene.add(line); document.body.append(renderer.domElement);
renderer.render(scene, camera);
</script>
</body> </html>
效果如下:

即其中的紫色的线就是我们创建的,而其他三个是坐标轴。
三、面
这里,我们可以绘制一个坐标平面,其中横竖都是二十条线,在照相机的拍摄下,如下所示:

完整代码如下所示:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>three.js</title>
<style>
* {
margin: ;
padding: ;
}
</style>
<script src="./three.js"></script>
</head> <body>
<script>
var scene = new THREE.Scene(); var axes = new THREE.AxesHelper();
scene.add(axes); var camera = new THREE.PerspectiveCamera(, window.innerWidth / window.innerHeight, , );
camera.position.x = ;
camera.position.y = ;
camera.position.z = ;
camera.up.x = ; camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff);
renderer.setSize(window.innerWidth, window.innerHeight); var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial({color:0x000000, opacity: 0.2});
var p1 = new THREE.Vector3(-, , );
var p2 = new THREE.Vector3(, , );
geometry.vertices.push(p1);
geometry.vertices.push(p2); for (var i = ; i <= ; i++) {
var line = new THREE.Line(geometry, material);
line.position.z = (i * ) - ;
scene.add(line); var line = new THREE.Line(geometry, material);
line.position.x = (i * ) - ;
line.rotation.y = * Math.PI / ;
scene.add(line); } document.body.append(renderer.domElement);
renderer.render(scene, camera);
</script>
</body> </html>
这里就是通过循环来创建线条,保证封闭即可,通过旋转方向保证形成一个正方形。
至此,我们就完成了点、线、面的绘制了。
webgl之绘图要点的更多相关文章
- Javascript高级编程学习笔记(99)—— WebGL(5) 绘图
绘图 WebGL只能绘制三种形状: 点 线 三角 其它的形状都是由上面的三种形状合成之后绘制到三维空间中的 执行绘图操作 WebGL 提供了两种方法: gl.drawElements() gl.dra ...
- WEBGL学习【七】画布绘图
主要是对WEBGL的绘图部分进行了进一步加强的认识和理解 <!DOCTYPE HTML> <html lang="en"> <head> < ...
- Web3D编程入门总结——WebGL与Three.js基础介绍
/*在这里对这段时间学习的3D编程知识做个总结,以备再次出发.计划分成“webgl与three.js基础介绍”.“面向对象的基础3D场景框架编写”.“模型导入与简单3D游戏编写”三个部分,其他零散知识 ...
- Javascript高级编程学习笔记(97)—— WebGL(3) WebGL上下文(1)
WebGL上下文 在支持WebGL的浏览器中,WebGL的名字为 "experimental-webgl",这是由于 webgl 的规范仍未制定完成 制定完成后名字就会改为简单的 ...
- WebGL学习笔记(一)
作者:朱金灿 来源:http://blog.csdn.net/clever101 (一)WebGL是什么? WebGL是一门在网页上显示三维图形的技术,你可以把它理解为把OpenGL从C/S端搬到了B ...
- WebGL绘制三角形
本文程序实现绘制一个三角形的任务,如下图. 整个程序包含两个文件,分别是: 1. HelloTriangle.html <!DOCTYPE HTML PUBLIC "-//W3C//D ...
- WebGL画点程序v3
本文程序实现画一个点的任务,如下图.其中,点的颜色由Javascript传到片元着色器程序中. 整个程序包含两个文件,分别是: 1. HelloPoint3.html <!DOCTYPE HTM ...
- WebGL画点程序v2
本文程序实现画一个点的任务,如下图.其中,点的位置坐标由Javascript传到着色器程序中,而不是直接给定("硬编码")在顶点着色器中. 整个程序包含两个文件,分别是: 1. H ...
- WebGL画点程序v1
本文程序实现画一个点的任务,如下图.其中,点的位置直接给定("硬编码")在顶点着色器中. 整个程序包含两个文件,分别是: 1. HelloPoint1.html <!DOCT ...
随机推荐
- 关于xftp上传文件状态错误的解决
新建一个文件夹,/usr/local/wwj 更改wwj权限 chmod 777 wwj 然后就可以上传了 如果还不行,就关闭防火墙
- Spring通过注解配置Bean
@Component: 基本注解, 标识了一个受 Spring 管理的组件@Repository: 标识持久层组件@Service: 标识服务层(业务层)组件@Controller: 标识表现层组件 ...
- window下切换python
自己的win10装了2.7和3.6版本的python.本不想装2.7的,但node.js的C++的编译居然用到2.X的python,没法子就装了2.7.那怎么切换呢? 为了方便使用,我在系统的path ...
- 关于Linux学习中的问题和体会
本科期间未开展过与之相关的课程,所以初次接触Linux难免有些问题!参照老师给的学习资料中内容,逐步解决了一些问题,但还有一些问题没解决,下面列举出自己遇到的一些问题. 1.在环境变量与文件查找专题中 ...
- linux 常用命令(个人记录)
Linux专家的秘诀:思考-实践-在思考-再实践...linux常用命令:root 管理员用户startx 进入shutdown -h now 立刻关机shutdown -r now 现在重新启动计算 ...
- 20155326 《Java程序设计》第8周学习总结
20155326 <Java程序设计>第8周学习总结 教材学习内容总结 NIO (1)NIO使用频道来衔接数据节点,在处理数据时,NIO可以让你设定缓冲区容量,在缓冲区中对感兴趣的数据区块 ...
- linux 下载文件
工作流程 1.tar pczvf file.tar.gz file 2.sz file.tar.gz:下载. 3.rm -i file.tar.gz: 删除.
- spring默认为单例模式
这两天看到一个bug,记录下. 在获取任务的时候,本来任务不是由这个柜员领取的,但是最后跑到那个柜员下面去了. 查看日志,发现两个任务的领取操作很近,日志是穿插着打的. 后来经人指点,说spring初 ...
- ubuntu16.04 LTS把下载源改为阿里云的源
为什么要切换下载源到国内的源上? Ubuntu的中国服务器下载速度很慢,我们可以尝试修改软件更新源,这样下载和更新软件的速度会加快很多. 一.linux系统版本: ubuntukylin-16.04- ...
- docker实用命令集合
1. 访问docker中的MySQL数据库: docker exec -it test_mysql_1 mysql -u root -p 2. 用docker命令导入或导出mysql数据: 导出doc ...