THREE.JS入门教程(2)着色器-上

译序
Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D。但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习。

0.简介
之前我已经给出了一篇《开始使用Three.js》。如果你还没有读过,你可能需要去读一下,本文的基础是在那一篇教程的基础上完成的。

我想讨论一下着色器。在Three.js帮助你免去了很多麻烦之前,原生WebGL就很优秀了。有的时候,你也许会想要完成一些特定的效果,或者想对呈现在你的屏幕上的东西钻研得更深入一些,那么着色器一定会进入你的视野。如果你像我一样,你也同样希望实现一些比上一篇教程中的基础更加有意思的东西。这篇教程中,我会讲解Three.js的基础,这些基础实际上为我们做了很多枯燥的工作。
在开始之前我还要说,这篇教程会有相当多的篇幅在解释着色器的代码,之后会有一篇教程会在着色器代码的基础上前进一点,利用着色器去做点什么。这是因为着色器shaders第一眼看上去并不易懂,需要一些解释。
1.两种着色器
WebGL没有固定的渲染管线,你无法直接使用一个黑盒子式的着色器(译者注:上个世纪的显卡基本都只支持固定渲染管线);WebGL提供的是可编程的管线,这种方式更强大但也更难理解和使用。长话短说,可编程渲染管线意味着编写程序的人要自己负责获取顶点并将它绘制在屏幕上了。着色器是渲染管线的一部分,有两种着色器:
1.顶点着色器
2.片元着色器
你应当知道的是,这两种着色器都完全运行在显卡的GPU上,我们将需要它们处理的数据从CPU上卸下,装到GPU上,减轻了CPU的复旦。现代的GPU对着色器需要的调用的运算类型都做了大幅优化,这样做很值得。
2.顶点着色器
基元形状,比如一个球体,是由顶点构成的,是吧?顶点着色器被依次传入这些顶点中的一个顶点,然后处理它。如何处理每个顶点是可以自由定制的,但顶点着色器有一个必做的事,就是为一个名为 gl_Position 的变量赋值,该变量是一个4维数组,表示该顶点最终在屏幕上的位置。这本身是个有意思的过程,因为我们实际上在谈论如何将一个三维坐标(一个具有x、y、z值得顶点)转化为,或者说投影到二维的屏幕上。谢天谢地,要是我们使用Three.js之类的工具,我们能够如此方便地访问到 gl_Position 。
3.片元着色器
现在我们有包含顶点的三维物体了,现在要将物体投影到二维屏幕上了,但颜色哪里去了?纹理和光照呢?这正是片元着色器要处理的。
和顶点着色器类似,片元着色器有一项必须完成的任务:设置或消除变量 gl_FragColor ,另一个四维浮点变量,也就是片元点最终的颜色。什么是片元?想象一个具有三个顶点的三角形,片元就是经过这三个顶点计算后的,所有在三角形内部的点。因此,片元值由顶点的值内插生成。如果一个顶点的颜色是红色,相邻顶点的颜色是蓝色,那么我们可以观测到颜色从红色顶点附近渐变,由红色变成紫色,最终在蓝色顶点附近变成蓝色。
4.着色器变量
说到着色器变量,有三种:Uniforma,Attributes和Varyings。当我第一次听到这三个词语时,我很困惑,因为它们和我之前用到的东西完全不匹配。但现在,你可以这样理解它们:
1.Uniforms变量既可以传入顶点着色器,也可以传入片元着色器,它们包含了哪些在整个渲染过程中保持不变的变量,比如,一个点光源的位置。
2.Attributes变量对应于每个顶点,它们只可以传入顶点着色器中,比如每个顶点都具有一个颜色。Attributes变量和顶点的关系是一一对应的。
3.Varyings变量是在顶点着色器中定义,并且准备传入给片元着色器的变量。为了确保这点,我们需要确保在两个着色器中变量的类型和命名完全一致。一个经典的应用是法线向量,因为在计算光照的时候需要用到法线。
在后面一篇教程中,我会使用这三种变量,你也会学习到这三种变量如何真正应用起来得。
现在,我们已经谈过了顶点着色器、片元着色器和三种着色器变量。是时候来看一个我们可以创建的最简单的着色器了。
5.Hello World(译者吐槽:能不能不要秀法语啊)
这儿有一个最简单的顶点着色器:


代码如下:

/**
* 每个顶点坐标乘以模型视图矩阵在乘以投影矩阵
* 获得在二维屏幕上的坐标
*/
void main() {
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}

一个最简单的片元着色器:


代码如下:

/**
* 将任意一个像元色设置为粉红
*/
void main() {
gl_FragColor = vec4(1.0, // R
0.0, // G
1.0, // B
1.0); // A
}

这就是全部了。如果现在直接运行的话,你就可以在屏幕上看到一个“无光”的粉红色形体。不是很复杂,是吗?

在顶点着色器中,我们通过Three.js传入了一些uniforms变量。有两个4×4的矩阵uniforms变量:模型视图矩阵和投影矩阵。你并不需要太了解这两个矩阵是怎么工作的。简单地说,这两个矩阵描述了三维点坐标如何投影成为二维屏幕上的坐标。

事实上,我只介绍了这两段简短的代码段。Three.js在你自己的着色器代码前已经将它们加进来了,所以你不必担心。实话说,Three.js还加了很多东西在你的代码前面,比如光照数据、节点颜色和节点法向量等等。如果没有Three.js你要亲自创建并设置这些对象,真的。
6.使用着色器材质


代码如下:

/**
* 假设我们可以使用JQuery
* 将着色器的代码文本从DOM中抽取出来
*/
var vShader = $('vertexshader');
var fShader = $('fragmentshader');
var shaderMaterial =
new THREE.ShaderMaterial({
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});

从这儿开始,Three.js将会编译并运行你的着色器,将其连接在你创建的材质上,材质又依附于你创建的mesh上。它并没有变得比真的更容易。也许是这样吧,但我们在考虑浏览器3D编程,我想你应该预期,这个话题是有一定复杂性的。

我们还可以像着色器材质添加另外两种属性:uniforms和attributes。他们可以是向量、整数或者浮点数,但是如我之前所说,uniforms变量在计算所有点的过程中保持不变,所以它们更加可能是单一的值,而attributes变量是对每个顶点而言的,所以他们应当是数组。在一个mesh中,attribute变量和顶点应当是一一对应的。
7.小结
这篇教程就到这里了,实际上我已经讲得很多了,但是在许多方面我都只是一掠而过。在下一篇教程中我会提供一个复杂的着色器,通过它我将传入一些attributes变量和uniforms变量来做一些模拟光照效果。
我将这篇教程的源码打包了,你可以下载下来作为参考

(0)

相关推荐

  • three.js快速入门【推荐】

    Three.js的核心五步就是: 1.设置three.js渲染器 2.设置摄像机camera 3.设置场景scene 4.设置光源light 5.设置物体object 1.设置three.js渲染器 三维空间里的物体映射到二维平面的过程被称为三维渲染. 一般来说我们都把进行渲染操作的软件叫做渲染器. 具体来说要进行下面这些处理. var renderer; function initThree(){ width = document.getElementById("box").clie

  • THREE.JS入门教程(1)THREE.JS使用前了解

    Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 国外网站 aerotwist.com 有六篇较为简单的入门教程,我尝试着将其翻译过来,与大家分享. 我在一些实验项目中使用了Three.js,我发现它对快速上手浏览器3D编程确实很有帮助.通过Three.js,你不仅可以创建相机.物体.光线.材质等等,还可以选择

  • Three.js快速入门教程

    引言 本文主要是讲解Three.js的相关概念,帮助读者对Three.js以及相关知识形成比较完整的理解. 近年来web得到了快速的发展.随着HTML5的普及,网页的表现能力越来越强大.网页上已经可以做出很多复杂的动画,精美的效果. 但是,人总是贪的.那么,在此之上还能做什么呢?其中一种就是通过WebGL在网页中绘制高性能的3D图形. OpenGL,WebGL到Three.js OpenGL大概许多人都有所耳闻,它是最常用的跨平台图形库. WebGL是基于OpenGL设计的面向web的图形标准,

  • THREE.JS入门教程(4)创建粒子系统

    译序 Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 嗨,又见面了.这么说我们已经开始学习Three.js了,如果你还没有看过之前三篇教程,建议你先读完.如果你已经读完前面的教程了,你可能会想做一些关于粒子的东西.让我们直面这个话题吧,每个人都爱粒子效果.不管你是否知道,你可以很轻易地创建它们. 1

  • THREE.JS入门教程(6)创建自己的全景图实现步骤

    译序 Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 全景图非常酷.使用Three.js做一个属于自己的全景图并不是那么困难. 要做一个全景图,你需要一个软件用来做一张全景图片(译者注:如果你没有那些特殊的设备).我使用了iPhone上的Microsoft Photosynth软件来制作. 1.环境

  • JS库之Three.js 简易入门教程(详解之一)

    开场白 webGL可以让我们在canvas上实现3D效果.而three.js是一款webGL框架,由于其易用性被广泛应用.如果你要学习webGL,抛弃那些复杂的原生接口从这款框架入手是一个不错的选择. 博主目前也在学习three.js,发现相关资料非常稀少,甚至官方的api文档也非常粗糙,很多效果需要自己慢慢敲代码摸索.所以我写这个教程的目的一是自己总结,二是与大家分享. 本篇是系列教程的第一篇:入门篇.在这篇文章中,我将以一个简单的demo为例,阐述three.js的基本配置方法.学完这篇文章

  • THREE.JS入门教程(5)你应当知道的十件事

    Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 嗨,这是我的第一篇关于如何写出好的代码的文章.和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习.在过去的几个月中,我在canvas标签上花了很多时间,我想如果把这段时间学到的关于WebGL和JavaScript的小技巧都写下来,

  • THREE.JS入门教程(3)着色器-下

    译序 Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. .简介 这是WebGL着色器教程的后半部分,如果你没看过前一篇,阅读这一篇教程可能会使你感到困惑,建议你翻阅前面的教程. 上一篇结束的时候,我们在屏幕中央画了一个好看的粉红色的球体.现在我要开始创建一些更加有意思的东西了. 在这一篇教程中,我们会先花点时间

  • THREE.JS入门教程(2)着色器-上

    译序 Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D.但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习. 0.简介 之前我已经给出了一篇<开始使用Three.js>.如果你还没有读过,你可能需要去读一下,本文的基础是在那一篇教程的基础上完成的. 我想讨论一下着色器.在Three.js帮助你免去了很多麻烦之前,原生WebGL就很优秀了.有的时候,你也许会想要完

  • p5.js入门教程之小球动画示例代码

    一.运动的小球 本节将用p5.js做一个在屏幕上运动的小球. 思路是用变量记录小球的位置,然后在draw()函数里对其做出改变,由于draw()函数会不断地运行(频率为FPS,默认60帧/秒),所以小球便产生了运动. 代码如下: var x=0; function setup() { createCanvas(400, 400); } function draw() { background(220); //width和height是关键词,分别是Canvas的宽和高 x+=2; ellipse

  • p5.js入门教程和基本形状绘制

    一.什么是p5.js 最近接触了一门数字媒体艺术类的课程,名为Interactivity,教的是p5.js. 主讲老师就是开发者之一--还是挺激动的. p5.js是一个为艺术家.设计师而开发的Javascript库,可以看作是Processing的Web版本.如果有Processing学习经验的话,p5.js上手会非常快. 至于p5.js有什么用,这个问题很难回答,因为我本身也是个初学者. 我目前觉得p5.js是一个很好的激发创意的工具,并且你可以将p5.js的内容嵌入网页,让你的网站更炫. 二

  • p5.js入门教程之图片加载

    一.preload()函数与图片上传 preload()函数是一个特殊的函数,它同setup()类似,只在程序开始时运行一次,但顺序在setup()之前. 一般我们会将媒体文件(图片.声音)加载的语句放在preload()中,因为preload()有一个特性就是不加载完毕,程序就不会开始,保证了程序运行时不会出错. 在加载图片之前,我们需要先将图片文件上传. 方法是: ①点击编辑器左上角的小三角展开文件目录. ②点击文件目录右上角小三角,展开菜单后Add File. ③可以直接将图片文件拖到框里

  • p5.js入门教程之鼠标交互的示例

    本文介绍了p5.js入门教程之鼠标交互的示例,分享给大家,具体如下: 一.鼠标交互常用关键词 p5.js提供了许多鼠标操作用的关键词与函数,常用的有: mouseIsPressed:关键词,若鼠标按下则为true,反之为false mouseButton:关键词,用来判断鼠标按下的是哪个键 案例如下: function setup() { createCanvas(400, 400); } function draw() { background(220); if (mouseIsPressed

  • p5.js入门教程之键盘交互

    一.键盘交互相关关键词与函数 keyIsPressed: 关键词,按下按键时为true,反之为false keyCode: 关键词,用于判断按下哪个按键 keyPressed():函数,按键按下时触发一次 keyReleased():函数,按键松开时触发一次 keyIsDown():函数,按下指定按键时返回true,反之为false 以下是一个较综合的案例,用wsad与zxcv控制小球移动: var x=200; var y=200; var speed=2; function setup()

  • p5.js入门教程之平滑过渡(Easing)

    一.跟随鼠标移动的小球 使用mouseX,mouseY可以创建一个跟随鼠标移动的小球. function setup() { createCanvas(400, 400); } function draw() { background(220); ellipse(mouseX,mouseY,20,20); } 二.让小球更加平滑的移动--使用Easing 一般制作精良的UI界面都会用到平滑移动这一效果,也就是利用了名为"Easing"的方法. 实现思路是另外设置变量以进行位置的过渡,代

随机推荐