WebGL开发技巧
一 、 标志板
标志板技术的基本原理是使用纹理距形绘制植物。技术的关键点如下:
1、每棵植物用一个纹理距形绘制,纹理距形采用内容为植物的透明背景纹理图。要使用恰当的混合 因子使植物 产生遮挡效果。
2、纹理距形朝向要永远正对摄像机。
案例关键代码:
表示棵植物,实现植物的绘制且根据摄像机位置计算植物面的朝向,具体代码如下:
QQQ:function SingleTree (x, z, yAngle, tg) {tg=new TreeGroup(); //获取植物的数组引用this.x=x; //该植物的x位置this.z=z; //该植物的y位置this.yAngle=yAngle; //植物纹理图的旋转角度this.tg=tg;this.drawSelf=function(ms, texture) {ms.pushMatrix(); //保护现场ms.translate(x, 0, z); //将植物平移到对应位置ms.rotate(yAngle, 0, 1, 0); //将纹理图旋转到对应角度tfd.drawSelf(ms, texture); //树的绘制ms.popMatrix(); //恢复现场}this.calculateBillboardDirection=function(){ //根据摄像机位置计算树木面的 var xspan=x-cx; //计算从植物位置到摄像机位置的x分量var zspan=z-cz; //计算从植物位置到摄像机位置的z分量if(zspan<=0) { //根据向量中的两个分量计算出纹理矩形绕y轴旋转的角度yAngle=180/Math.PI *(Math.atan(xspan/zspan));} else{yAngle=180+180/Math.PI *(Math.atan(xspan/zspan)); }}}
表示一组植物,其中包含植物 的位置 以及每个植物的朝向各绘制,代码如下:
function TreeGroup(gl) {this.treeGroupadd=function(gl) { //向数组中添加植物的位置alist.push(new SingleTree(0,0,0, this)); //植物的位置alist.push(new SingleTree(8,0,10, this)); //植物的位置alist.push(new SingleTree(5.7,5.7,0, this)); //植物的位置alist.push(new SingleTree(0, -8,0, this)); //植物的位置alist.push(new SingleTree(-5.7,5.7,0, this)); //植物的位置alist.push(new SingleTree(-8,0,0, this)); //植物的位置alist.push(new SingleTree(-5.7, -5.7,0, this)); //植物的位置alist.push(new SingleTree(0,8,0, this)); //植物的位置alist.push(new SingleTree(5.7, -5.7,0, this)); //植物的位置}this.calculateBillboardDirection=function(){ //计算列表中每个树木的朝向 for(var i=0; i<alist.length; i++){ //循环遍历数组中的元素 alist[i].calculateBillboardDirection(); //计算每个植物纹理矩形的朝向}}this.drawSelf=function(ms, texture) { //绘制列表中的每个树木 for(var i=0; i<alist.length; i++){ //循环遍历数组中的元素alist[i].drawSelf(ms, texture); //调用drawSelf方法绘制植物}}}
二、 灰度图地形
1、基本思想 :灰度图地形就是用网格表示地形,同时提供一幅对应尺寸的灰度图,根据灰度图的每个像素的灰度来确定网格顶点的海拔,值为0表示最低位置,值为255表示最高位置 。可用如下公式计算顶点的海拔高度:
实际海拔=最低海拔+最大高差X像素值 /255.0
2、过程纹理:
过程纹理是通过计算在运行时生成纹理,而不是从图像文件中加载,可以用来增强动态地形效果。具体使用过程如下:
(1)绑定纹理,为纹理分配编号,传送过程纹理起始y坐标,跨度进入渲染管线。
(2)在顶点着色器中增加将顶点y坐标通过out类型变量传递给片元着色器。
(3)在片元着色器中同时使用两种纹理对地形着色,小于过程纹理起始y坐标用编号0着色,大于起如y坐标加跨度时用编号1着色,介于两者之间用两者按比例混合着色。
3、Mipmap地形
使用此技术可以改善地形中远处山体比近处山体更加清晰的问题,还可以提升性能。
需要纹理空间接近普通纹理的两倍。使用步骤 如下:
(1)设置纹理采样方式为Mipmap。
(2)自动生成Mipmap系列纹理图
三、高真实感地形
灰度图地形缺点: 无光照效果,层次感,山地各个方向上视觉效果没有差异。
基本思路: (1)计算每个顶点位置的同时计算其法向量,增加光照效果
(2)纹理图增加为6幅,基中一幅为基础颜色纹理图,有四幅是不同的外观的细节纹理 ,包含灰色岩石、硬泥土、大理石、绿草皮,另外一幅作为过程纹理图,其R、G、B、,A色彩通道分别记录地形上每个位置 的细节纹理系数。
四、天空盒与天空穹
天空盒:将场景放置在一个很大的立方体中,立方体每个面是一个纹理正方形,用于观察场景的摄像机需要放置在天空盒立方体的内部。
天空穹:使用一个半球面模拟天空,此半球面需要天空的纹理图。
五、简单镜像
基本原理 :WebGL绘制实体时,采用系统默认的逆时针卷绕方式,在绘制镜像时,由于镜像和实体是关于反射面对称 ,绘制镜像时采用顺时针卷绕方式。
六、 非真实感绘制
真实感绘制: 模拟现实世界中真实物体的各种光影效果,包括物体的颜色以及光照情况等。使用较多颜色数,达到真实感 。
非真实感绘制:使用较少的颜色数进行绘制达到非真实效果,从数学角度上讲,就是将颜色取值从连续函数转化为离散函数。
实现策略:计算物体光照强度,取值(0.0-1.0),使用光照强度作为S纹理坐标,同时采用固定的T纹理坐标,进行纹理采样,对物体边缘进行描绘(通常采用黑色)
七、 描述边效果
沿法线挤出轮廓:将物体没法线挤出一些,用需要描边的纯色进行绘制,然后用正常的方式绘制 物体,从而形成一个轮廓。
从视空间挤出轮廓: 将顶点坐标以及法向量通过乘以最终变换距阵的方式变换到视空间,然后将视空间中的顶点坐标沿变换后视空间中的法向量挤出。