WebGL编程指南
  • 推荐0
  • 收藏0
  • 浏览882

WebGL编程指南

Kouichi Matsuda,Rodger Lea(松田浩一,罗杰·李) (作者)  谢光磊 (译者)

  • 书  号:978-7-121-22942-8
  • 出版日期:2014-06-18
  • 页  数:500
  • 开  本:16(178*232)
  • 出版状态:上市销售
  • 原书名: WebGL Programming Guide: Interactive 3D Graphics Programming with WebGL
  • 原书号:0321902920
  • 维护人:张春雨
无需插件,用WebGL就可以达到将网页3D化的目的,尤其是在游戏、用户交互和可视化信息等方面表现的十分出色。即使你没有任何HTML5、JavaScript、3D 图像制作、数学或 OpenGL知识,也可以通过学习本书内容的对交互式WebGL 3D编程快速上手。
这是HTML5的优势之一,也是游戏及其他Web开发外来方向,国外已有大量图书,目前我们已经落后,但作为第一本,选择AWP风险可控。
WebGL 是一项用以在浏览器中绘制、显示三维计算机图形(“三维图形”),并与之交互的技术。曾经只有高端的计算机或专门的游戏终端才能渲染三维图形,因为这需要大量复杂的编程才能实现,然而随着个人计算机,以及——更重要的——浏览器的性能的提高,使用网页技术渲染三维图形也已经成为可能。本书全面讲授了WebGL 技术,带领读者一步一个脚印地编写WebGL 程序。和OpenGL 与Direct3D 不同,WebGL 程序存在于网页中,可以在浏览器里直接执行,而不必安装任何特殊的插件或库。因此,你只需要最普通的计算机环境,就可以开始进行开发或运行示例程序;而且,一切都是基于网页的,你可以方便地将WebGL 程序作为网页发布出去。此外,由于WebGL 是基于网页的,所以该技术的愿景之一,就是同一个程序能够通过浏览器运行在多种设备上,比如智能手机、平板电脑、游戏终端等。这份远大的野心,意味着WebGL 技术期望对开发者社区产生深远的影响,并在不久的将来成为图形开发的最佳选择之一。
  本书的读者群
  在写本书时,我希望本书的读者群主要由两类人构成:希望在网页中加入三维图形的Web 开发者,以及希望将三维图形搬上网页环境的三维图形开发者。如果你是前一类读者,即Web 开发者,你可能对标准的Web 技术,如HTML 和JavaScript,已经很熟悉了,你希望知道如何向网页或Web 程序中插入三维图形,那么WebGL 将会向你提供简单且强大的解决方案,你可以使用三维图形来增强Web 程序的用户界面(UI),或者开发更复杂的三维程序,比如运行在浏览器中的三维网页游戏。
  如果你是第二类目标读者群中的一员,你可能已经具有使用主流三维应用程序接口(API),如Direct3D 或OpenGL 进行开发的经验,你希望知道如何在网页环境中应用这些知识。我想你一定对开发出能够在现代浏览器中运行的复杂三维程序更感兴趣。
  然而,这本书也适用于更加广泛的读者群。因为本书假定读者不具有任何关于二维或三维图形编程的背景,所以几乎是手把手地向读者传授WebGL 的特性。因此,我想以下读者可能也会对本书感兴趣:所有希望了解网页技术与图形技术交集的程序员;学习二维或三维图形学的学生,因为WebGL 只需要一个浏览器即可上手,无须安装一整套开发环境。探索最前沿技术,试图在安卓手机、iPhone 等移动设备的最新版浏览器中有所作为的Web 开发者。
  本书涵盖的内容
  本书涵盖了WebGL 1.0 API 包含的几乎所有的JavaScript 方法,你可以学到WebGL、HTML、JavaScript 是如何联系的,如何建立和运行WebGL 程序,如何使用JavaScript 控制复杂的三维“着色器”程序。本书详细讲述了如何编写顶点着色器和片元着色器,如何实现该机的渲染技术,如逐顶点光照、阴影、基本的交互操作(如选中三维物体)等。
  本书的每一章将开发若干个可用的,具有一定功能的WebGL 示例程序,并通过这些示例程序介绍WebGL 的关键特性。在读完本书之后,你就能够编写出能够充分利用浏览器的编程能力和图形硬件的WebGL 程序。
  本书的结构
  本书一步一步地介绍了WebGL API 以及相关的Web API,以帮助你建立起关于WebGL 的知识结构。
  第1章——WebGL 概述
  这一章简要介绍了WebGL,讨论了WebGL 的历史起源,概括了它的一些关键特性和优点。这一章还介绍了WebGL 与HTML5 以及 JavaScript 的关系,介绍了我们可以使用哪些浏览器开始探索WebGL。
  第2章——WebGL 入门
  这一章通过建立几个示例程序,依次介绍了canvas 元素和WebGL 的核心函数。每个示例都是用JavaScript 编写的,并使用WebGL 在网页上绘制一个简单的形状。示例程序突出了以下几点:(1)WebGL 如何使用canvas 元素并在其上绘图;(2)HTML 文件和用JavaScript 编写的WebGL 代码文件的连接;(3) 简单的WebGL 绘图函数;(4) 着色器程序在WebGL 中的地位。
  第3章——绘制和变换三角形
  这一章在之前的基础上,探索了如何绘制较为复杂的图形,如何操作三维空间中的这些图形。这一章主要包括:(1) 三角形的关键作用,以及WebGL 对绘制三角形的支持;(2)使用多个三角形绘制出其他图形;(3) 使用方程对三角形进行基本的变换,如平移、旋转和缩放等;(4) 矩阵可以简化变换的运算。
  第4章——高级变换和动画基础
  这一章将更加深入地探索变换的原理,并开始将变换用于动画中。你将:(1) 了解一个矩阵变换库,该库将矩阵变换的数学运算细节隐藏了起来;(2) 使用矩阵库将多次变换组合起来;(3) 在矩阵库的帮助下,探索如何实现简单的动画。这些技术是构建复杂WebGL 程序的基石,在后面几章的示例程序中都会用到。
  第5章——颜色和纹理
  这一章在之前几章的基础上,进一步深入研究了以下三个问题:(1) 除了顶点坐标数据,我们还可以将颜色信息等其他数据传入顶点着色器;(2) 顶点着色器和片元着色器之间的光栅化过程,将图形转化为了片元;(3) 如何将图像(或纹理)贴到图形或模型的表面。这一章是有关WebGL 核心功能的最后一章。
  第6章——OpenGL ES 着色器语言(GLSL ES)
  这一章不涉及WebGL 示例程序,而是详细介绍了OpenGL ES 着色器语言(GLSL ES)的核心特性,包括:(1) 数据、变量、变量类型;(2) 矢量、矩阵、结构体、数组和取样器;(3) 运算符、流程控制和函数;(4)attribute 变量、uniform 变量和varying 变量;(5)精度限定字;(6) 预处理过程和编程准则。在这一章的最后,你将对GLSLES 有很好的理解,并学会使用该语言来编写各种着色器。
  第7章——进入三维世界
  这一章将带领读者首次进入三维世界,探索如何将以前学到的一切从二维空间搬到三维空间中。具体地,你将探索:(1) 如何在三维空间中表示观察者;(2) 如何控制可视的三维空间体积;(3) 裁剪;(4) 物体的前后关系;(5) 绘制一个三维物体——立方体。所有这些问题都会对三维场景的渲染和最终呈现给用户的样子产生重大的影响。为了构建三维场景,深入理解并掌握它们是必须的。
  第8章——光照
  这一章主要研究如何实现光照,研究了不同类型的光源及其对三维场景产生的效果。如果想要使三维场景逼真,光照是必需的,因为光照会增强场景的深度感。
  本章讨论了以下几个关键点:(1) 着色、阴影和不同类型的光源产生的光,包括点光源光、平行光和环境光;(2) 三维场景中两种主要的反射光类型:漫反射和环境反射;(3)着色的细节,以及如何实现光照效果时场景更像是三维的。
  第9章——层次模型
  这一章是关于如何使用WebGL 的核心特性的最后一章。在这一章结束时,你将掌握WebGL 的所有基础知识,并完全能够创建逼真和可交互的三维场景了。这一章的重点是层次模型。层次模型能够使复杂模型,如游戏角色、机器人,甚至是真人模型产生动作,而不仅仅是生硬的立方体。
  第10章——高级技术
  这一章在整本书的基础上,介绍了若干有用的高级技术,提供了一些关键的工具,帮助你构建出可交互的、令人惊叹的三维图形。每一项技术都通过一个完整的示例来展示,你可以在自己的WebGL 程序中重用其中的代码。
  附录A——WebGL 无须交换缓冲区
  这篇附录解释了为什么WebGL 无须像OpenGL 那样交换缓冲区。
  附录B——GLSL ES 1.0 内置函数
  这篇附录提供了一份包含所有OpenGL ES 着色器语言内置函数的参考列表。
  附录C——投影矩阵
  这篇附录提供了Matrix4.setOrtho() 函数和Matrix4.setPerspective() 函数生成的投影矩阵。
  附录D——WebGL/OpenGL :左手还是右手坐标系?
  这篇附录介绍了WebGL 和OpenGL 的内在坐标系统,并从技术上解释了为什么我们说WebGL 和OpenGL 对采取左手坐标系或右手坐标系是中立的。
  附录E——逆转值矩阵
  这篇附录解释了模型矩阵的逆转值矩阵为什么可以用来变换法向量。
  附录F——从文件中加载着色器
  这篇附录解释了如何从文件中加载着色器程序。
  附录G——世界坐标系和本地坐标系
  这篇附录介绍了两种不同的坐标系统,以及如何在三维图形中使用它们。
  附录H——关于WebGL 的浏览器设置
  这篇附录介绍了浏览器的高级设置方法,以确保WebGL 程序能够正确运行,以及程序不能正确运行时的应对方法。
  支持WebGL 的浏览器
  在撰写本书之时,WebGL 被Chrome、Firefox、Safari、Opera 浏览器支持。遗憾的是,有一些浏览器如IE9(Microsoft Internet Explorer)并不支持WebGL。在本书中,我们使用Google 发布的Chrome 浏览器。Chrome 不仅支持WebGL,还支持一些有用的特性,如调试WebGL 的控制台函数。我们已经在以下环境中检查过本书的所有示例程序,都能够正确运行。在任何支持WebGL 的浏览器中,这些程序也应当能够正确运行。
  表P.1 PC 环境
  浏览器 Chrome(25.0.1364.152 m)
  操作系统 Windows7 & 8
  显卡 NVIDIA Quadro FX 380,NVDIA GT X 580,NVDIA GeForce GTS 450,Mobile Intel4 Series Express Chipset Family,AMD Radeon HD 6970
  参考这个页面,以获取最新的、关于可能导致问题的硬件列表。
  为了不受阻碍地开始学习本书,你应该去下载Chrome(或者你中意的其他浏览器)。
  在第3 章,点击示例程序文件HelloTriangle.html,如果你看到如图P.1 所示的红色三角形,就说明WebGL 正常工作了。
  图P.1 加载HelloTriangle 显示红色三角形
  如果你没有看到红色三角形,那么请参考附录H,改变你的浏览器设置以加载WebGL 程序。

目录

第1 章 WebGL 概述
WebGL 的优势
使用文本编辑器开发三维应用
轻松发布三维图形程序
充分利用浏览器的功能
学习和使用WebGL 很简单
WebGL 的起源
WebGL 程序的结构
总结
第2 章 WebGL 入门
Canvas 是什么?
使用<canvas> 标签
DrawRectangle.js
最短的WebGL 程序:清空绘图区
HTML 文件(HelloCanvas.html)
JavaScript 程序(HelloCanvas.js)
用示例程序做实验
绘制一个点(版本1)
HelloPoint1.html
HelloPoint1.js
着色器是什么?
使用着色器的WebGL 程序的结构
初始化着色器
顶点着色器
片元着色器
绘制操作
WebGL 坐标系统
用示例程序做实验
绘制一个点(版本2)
使用attribute 变量
示例程序(HelloPoint2.js)
获取attribute 变量的存储位置
向attribute 变量赋值
gl.vertexAttrib3f() 的同族函数
用示例程序做实验
通过鼠标点击绘点
示例程序(ClickedPoints.js)
注册事件响应函数
响应鼠标点击事件
用示例程序做实验
改变点的颜色
示例程序(ColoredPoints.js)
uniform 变量
获取uniform 变量的存储地址
向uniform 变量赋值
gl.uniform4f() 的同族函数
总结
第3 章 绘制和变换三角形
绘制多个点
示例程序(MultiPoint.js)
使用缓冲区对象
创建缓冲区对象(gl.createBuffer())
绑定缓冲区(gl.bindBuffer())
向缓冲区对象中写入数据(gl.bufferData())
类型化数组
将缓冲区对象分配给attribute 变量(gl.vertexAttribPointer())
开启attribute 变量(gl.enableVertexAttribArray())
gl.drawArrays() 的第2 个和第3 个参数
用示例程序做实验
Hello Triangle
示例程序(HelloTriangle.js)
基本图形
用示例程序做实验
Hello Rectangle(HelloQuad)
用示例程序做实验
移动、旋转和缩放
平移
示例程序(TranslatedTriangle.js)
旋转
示例程序(RotatedTriangle.js)
变换矩阵:旋转
变换矩阵:平移
4×4 的旋转矩阵
示例程序(RotatedTriangle_Matrix.js)
平移:相同的策略
变换矩阵:缩放
总结
第4 章 高级变换与动画基础
平移,然后旋转
矩阵变换库:cuon-matrix.js
示例程序(RotatedTriangle_Matrix4.js)
复合变换
示例程序(RotatedTranslatedTriangle.js)
用示例程序做实验
动画
动画基础
示例程序(RotatingTriangle.js)
反复调用绘制函数(tick())
按照指定的旋转角度绘制三角形(draw())
请求再次被调用(requestAnimationFrame())
更新旋转角(animate())
用示例程序做实验
总结
第5 章 颜色与纹理
将非坐标数据传入顶点着色器
示例程序(MultiAttributeSize.js)
创建多个缓冲区对象
gl.vertexAttribPointer() 的步进和偏移参数
示例程序(MultiAttributeSize_Interleaved.js)
修改颜色(varying 变量)
示例程序(MultiAttributeColor.js)
用示例程序做实验
彩色三角形(ColoredTriangle.js)
几何形状的装配和光栅化
调用片元着色器
用示例程序做实验
varying 变量的作用和内插过程
在矩形表面贴上图像
纹理坐标
将纹理图像粘贴到几何图形上
示例程序(TexturedQuad.js)
设置纹理坐标(initVertexBuffers())
配置和加载纹理(initTextures())
为WebGL 配置纹理(loadTexture())
图像Y 轴反转
激活纹理单元(gl.activeTexture())
绑定纹理对象(gl.bindTexture())
配置纹理对象的参数(gl.texParameteri())
将纹理图像分配给纹理对象(gl.texImage2D())
将纹理单元传递给片元着色器(gl.uniform1i())
从顶点着色器向片元着色器传输纹理坐标
在片元着色器中获取纹理像素颜色(texture2D())
用示例程序做试验
使用多幅纹理
示例程序(MultiTexture.js)
总结
第6 章 OpenGL ES 着色器语言(GLSL ES)
回顾:基本着色器代码
GLSL ES 概述
你好,着色器!
基础
执行次序
注释
数据值类型(数值和布尔值)
变量
GLSL ES 是强类型语言
基本类型
赋值和类型转换
运算符
矢量和矩阵
赋值和构造
访问元素
运算符
结构体
赋值和构造
访问成员
运算符
数组
取样器(纹理)
运算符优先级
程序流程控制:分支和循环
if 语句和if-else 语句
for 语句
continue、break 和discard 语句
函数
规范声明
参数限定词
内置函数
全局变量和局部变量
存储限定字
const 变量
Attribute 变量
uniform 变量
varying 变量
精度限定字
预处理指令
总结
第7 章 进入三维世界
立方体由三角形构成
视点和视线
视点、观察目标点和上方向
示例程序(LookAtTriangles.js)
LookAtTriangles.js 与RotatedTriangle_Matrix4.js
从指定视点观察旋转后的三角形
示例程序(LookAtRotatedTriangles.js)
用示例程序做实验
利用键盘改变视点
示例程序(LookAtTrianglesWithKeys.js)
独缺一角
可视范围(正射类型)
可视空间
定义盒状可视空间
示例程序(OrthoView.html)
示例程序(OrthoView.js)
JavaScript 修改HTML 元素
顶点着色器的执行流程
修改near 和far 值
补上缺掉的角(LookAtTrianglesWithKeys_ViewVolume.js)
用示例程序做实验
可视空间(透视投影)
定义透视投影可视空间
示例程序(perspectiveview.js)
投影矩阵的作用
共冶一炉(模型矩阵、视图矩阵和投影矩阵)
示例程序(PerspectiveView_mvp.js)
用示例程序做实验
正确处理对象的前后关系
隐藏面消除
示例程序(DepthBuffer.js)
深度冲突
立方体
通过顶点索引绘制物体
示例程序(HelloCube.js)
向缓冲区中写入顶点的坐标、颜色与索引
为立方体的每个表面指定颜色
示例程序(ColoredCube.js)
用示例程序做实验
总结
第8 章 光照
光照原理
光源类型
反射类型
平行光下的漫反射
根据光线和表面的方向计算入射角
法线:表面的朝向
示例程序(LightedCube.js)
环境光下的漫反射
示例程序(LightedCube_ambient.js)
运动物体的光照效果
魔法矩阵:逆转置矩阵
示例程序(LightedTranslatedRotatedCube.js)
点光源光
示例程序(PointLightedCube.js)
更逼真:逐片元光照
示例程序(PointLightedCube_perFragment.js)
总结
第9 章 层次模型
多个简单模型组成的复杂模型
层次结构模型
单关节模型
示例程序(JointMode.js)
绘制层次模型(draw())
多节点模型
示例程序(MultiJointModel.js)
绘制部件(drawBox())
绘制部件(drawSegments())
着色器和着色器程序对象:initShaders() 函数的作用
创建着色器对象(gl.createShader())
指定着色器对象的代码(gl.shaderSource())
编译着色器(gl.compileShader())
创建程序对象(gl.createProgram())
为程序对象分配着色器对象(gl.attachShader())
连接程序对象(gl.linkProgram())
告知WebGL 系统所使用的程序对象(gl.useProgram())
initShaders() 函数的内部流程
总结
第10 章 高级技术
用鼠标控制物体旋转
如何实现物体旋转
示例程序(RotateObject.js)
选中物体
如何实现选中物体
示例程序(PickObject.js)
选中一个表面
示例程序(PickFace.js)
HUD(平视显示器)
如何实现HUD
示例程序(HUD.html)
示例程序(HUD.js)
在网页上方显示三维物体
雾化(大气效果)
如何实现雾化
示例程序(Fog.js)
使用w 分量(Fog_w.js)
绘制圆形的点
如何实现圆形的点
示例程序(RoundedPoint.js)
α 混合
如何实现α 混合
示例程序(LookAtBlendedTriangles.js)
混合函数
半透明的三维物体(BlendedCube.js)
透明与不透明物体共存 .
切换着色器
如何实现切换着色器
示例程序(ProgramObject.js)
渲染到纹理
帧缓冲区对象和渲染缓冲区对象
如何实现渲染到纹理
示例程序(FramebufferObject.js)
创建帧缓冲区对象(gl.createFramebuffer())
创建纹理对象并设置其尺寸和参数
创建渲染缓冲区对象(gl.createRenderbuffer())
绑定渲染缓冲区并设置其尺寸(gl.bindRenderbuffer(),
gl.renderbufferStorage())
将纹理对象关联到帧缓冲区对象(gl.bindFramebuffer(),
gl.framebufferTexture2D())
将渲染缓冲区对象关联到帧缓冲区对象(gl.framebufferRenderbuffer())
检查帧缓冲区的配置(gl.checkFramebufferStatus())
在帧缓冲区进行绘图
绘制阴影
如何实现阴影
示例程序(Shadow.js)
提高精度
示例程序(Shadow_highp.js)
加载三维模型
OBJ 文件格式
MTL 文件格式
示例程序(OBJViewer.js)
自定义类型对象
示例程序(OBJViewer.js 解析数据部分)
响应上下文丢失
如何响应上下文丢失
示例程序(RotatingTriangle_contextLost.js)
总结
附录A WebGL 中无须交换缓冲区
附录B GLSL ES 1.0 内置函数
角度和三角函数
指数函数
通用函数
几何函数
矩阵函数
矢量函数
纹理查询函数
附录C 投影矩阵
正射投影矩阵
透视投影矩阵
附录D WebGL/OpenGL :左手还是右手坐标系?
示例程序(CoordinateSystem.js)
隐藏面消除和裁剪坐标系统
裁剪坐标系和可视空间
什么是对的?
总结
附录E 逆转置矩阵
附录F 从文件中加载着色器
附录G 世界坐标系和本地坐标系
本地坐标系
世界坐标系
变换与坐标系
附录H WebGL 的浏览器设置

本书勘误

印次
  • 页码:35,36  •  印次: 18

    35 页:“Y 轴是垂直的(正方向为下)”应为“Y 轴是垂直的(正方向为上)”
    36 页:上边缘和下边缘:(-1,0,0.0,0.0)和(1,0,0.0,0.0)应为“上边缘和下边缘:(0.0,-1,0,,0.0)和(0.0,1.0,0,0.0,0.0)
    左边缘和右边缘:(0.0,-1,0,,0.0)和(0.0,1.0,0,0.0,0.0)应为“左边缘和右边缘:(-1,0,0.0,0.0)和(1,0,0.0,0.0)”

    lkr 提交于 2022/4/29 16:52:37
    张春雨 确认于 2024/2/5 13:44:20
  • 页码:50  •  行数:12,13  •  印次: 9

    代码第56 57行
    canvas.height 应为 canvas.width。
    canvas.width 应为 canvas.height。

    siaikin 提交于 2019/6/2 16:50:53
    张春雨 确认于 2019/7/11 13:05:07
  • 页码:200  •  印次: 1

    struct light {
    vec4 color;
    vec3 position; // “广元位置” 应为 “光源位置”
    }

    Lu8 提交于 2021/3/9 11:09:23
    张春雨 确认于 2021/4/15 16:28:33

读者评论

  • 书上的源码下载不到了,怎么弄

    刘国发表于 2020/2/20 9:34:24
    • 页面有下载了,请看一下。

      张春雨发表于 2020/6/15 14:57:37

下载资源