0%

WebGL高级技术

物体旋转

使用模型视图投影矩阵变化顶点坐标。

根据鼠标位移差值,计算旋转矩阵。

1
2
3
4
5
viewProjMatrix.setPerspective()
viewProjMatrix.lookAt()
------
g_MvpMatrix.set(viewProjMatrix)
g_MvpMatrix.roate()

选中物体

使用颜色缓冲区方法(简单)
  1. 当点击时,整个对象重绘成单一红色。

  2. 读取鼠标点击处的颜色。

  3. 使用立方体原来的颜色重绘。

  4. 对比第二步读取到的颜色。

1
2
gl.readPixels(x, y, width, height, format, type, pixels)
//读取颜色缓冲区中x,y,width,height参数确定的像素值,保存在pixels中

例如对于立方体的多个表面,将表面编号写入组成每个表面各个顶点,将编号数组传入顶点着色器。当点击时,首先在顶点着色器中将每个面根据编号计算每个面的颜色α值,并在颜色缓冲区中重绘。即可通过readPixels获取颜色值,得到点击的表面编号。之后根据表面编号,再传入顶点着色器对相应面进行所需操作。

HUD(平视显示器)

再三维场景上叠加文本或者二维图形信息。

使用两个canvas叠加。背景透明。

雾化

线性雾化:雾化程度取决于与视点之间的距离。某一点的雾化程度可以定义成雾化因子。

片元颜色 = 物体表面颜色 x 雾化因子 + 雾的颜色 x (1 - 雾化因子)

w分量

gl_Position的w分量为顶点的视图坐标的z分量乘以-1。在视图坐标系中,视点在原点,视线沿着Z轴负方向,观察者看到的物体其视图坐标系值z分量都为负数,所以其w值可以直接近似为顶点与视点的距离。

绘制圆形点

将方形的点剔除不需要的片元。

片元着色器中内置变量

1
2
vec4 gl_FragCoord  //片元窗口坐标
vec4 gl_PointCoord //片元在被绘制的点内的坐标(0.0到1.0)

在片元着色器中,将距离点的中心(0.5,0.5)超过0.5的片元剔除。

1
2
distance(gl_PointCoord, vec2(0.5, 0.5)) //计算距离函数
discard //放弃当前片元语句

α混合

实现半透明效果,需要用到颜色的α分量。需要开启WebGL的α混合功能。

1
2
3
4
gl.enable(gl.BLEND) //开启混合功能
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHAD)
//指定混合函数 参数指定进行混合操作的函数。
//加法混合---gl.blendFunc(gl.SRC_ALPHA, gl.ONE)
混合函数

混合后的颜色 = 源颜色 * src_factor + 目标颜色 * dst_factor

源颜色: 待混合进去的颜色。上层颜色

目标颜色: 待被混合的颜色。下层颜色

透明与不透明共存

透明后如果开启了隐藏面消除功能,则被隐藏的片元则不会绘制。所以不会发生混合过程。但是关闭隐藏面消除功能会使物体前后关系乱套。所以要实现透明与不透明共存:

  1. 开启隐藏面消除功能 gl.enable(gl.DEPTH_TEST)
  2. 绘制所有不透明物体
  3. 锁定用于隐藏面消除的深度缓冲区的写入操作,使其只读深度缓冲区: 是一个中间对象,帮助进行隐藏面消除,存储深度信息:每个像素的归一化坐标z值。其对比z值,舍弃隐藏的片元,不会写入颜色缓冲区。gl.depthMask(false)
  4. 绘制所有半透明物体,需要按照深度排序,从后往前绘制。
  5. 释放深度缓冲区,可读可写。gl.depthMask(true)

切换着色器

当对于不同物体需要不同着色器进行绘制时,需要切换使用。

为多个着色器对象创建多个程序对象,使用gl.useProgram(program)进行切换。

渲染到纹理

加载三维模型

OBJ文件格式
  1. (#)开头行为注释

  2. 材质文件存储在外部MTL格式文件。mtllib<外部材质文件名>

  3. 模型名称 <模型名称>

  4. 顶点坐标 v x y z [w]

  5. 指定某个材质 。列举使用这个材质的表面。材质被定义在引用的MTL文件中。

    1
    2
    3
    4
    usemtl<材质名>
    f v1 v2 v3 v4 ···

    f v1//vn1 v2//vn2 v3//vn3 ···

    其中v1为顶点索引值,从1开始。

    vn1,vn2为法线向量索引,从1开始。

MTL文件格式
  1. 定义一个新材质newmtl<材质名>

  2. 使用Ka、Kd和Ks定义表面环境色、漫反射、高光色。使用RGB格式,区间为[0.0,1.0]

    1
    2
    3
    Ka 0.000000 0.000000 0.000000
    Kd 0.000000 0.000000 0.000000
    Ks 0.000000 0.000000 0.000000
  3. Ns指定高光色权重,Ni指定表面光学密度,d指定透明度,illum指定光照模型。

响应上下文丢失

当其他程序接管了图形硬件,或者操作系统休眠,浏览器会失去这些资源,webgl绘图上下文就会丢失。

1
2
webglcontextlost事件 当WebGL上下文丢失时触发
webglcontextrestored事件 当浏览器完成WebGL系统重置后触发

当丢失上下文时,getWebGLContext()函数获得渲染上下文对象gl就失效了。在浏览器重置WebGL后需要重新完成在之前gl对象上的所有操作。如创建缓冲区,纹理对象,初始化着色器等。