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纹理坐标,进行纹理采样,对物体边缘进行描绘(通常采用黑色)

七、 描述边效果

        沿法线挤出轮廓:将物体没法线挤出一些,用需要描边的纯色进行绘制,然后用正常的方式绘制 物体,从而形成一个轮廓。

        从视空间挤出轮廓: 将顶点坐标以及法向量通过乘以最终变换距阵的方式变换到视空间,然后将视空间中的顶点坐标沿变换后视空间中的法向量挤出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值