WebGL2混合与雾

混合技术

一、混合基本技术 

混合技术就是将两个片元调和,主要通过各种测试将准备进入帧缓冲(源片元)与帧缓冲中原有片元(目标片元)按照设定的比例加权计算出最终片元的颜色值 。

两种常用 组合 :

        源因子为SRC_ALPHA,目标因子为ONE_MINUS_SRC _ALPHA,若源片元是透明的,则根据透明度透过后面的内容,若源片元不透明,则仅能看到源片元。

        源因子为SRC_COLOR,目标因子为ONE_MINUS_SRC_COLOR,此组合可以实现滤光镜效果,也就是平时透过有色眼镜或玻璃窗观察事物的感觉。

关键代码 

//启用混合模式并绘制滤光镜
frunction drawFrame(){
      ....//此处省略绘制场景中物体的代码
      gl.enable(gl.BLEND)   //开启混合
      gl.blendFunc(gl.SRC_COLOR,gl.ONE_MINUS_SRC_COLOR)  //设置混合因子
      .....
      gl.disable(gl.BLEND)
      
}

二、雾的原理与优势

有很多数学原型可以实现雾效果,以下介绍两个模型

线性模型:

        f=max(min((end-dist)/(end-start),1.0),0.0)

f为雾化因子,取值范围为0.0-1.0,值 为0表示雾浓,值 为1表示雾淡

dist 为当前要绘制的片元离摄像机的距离

end表示一个特定的距离值,片元距摄像机的距离超过end时,雾化因子为0

start表示一个特定的距离值 , 片元距摄像机的距离小于start时,雾化因子为1

非线性模型:

        f=1.0-smoothstep(sttart,end,dist)

一般情况下采用此公式进行计算可以取得比线性公式更好的效果。

三 、雾的简单实现

关键代码

顶点着色器

 #version 300 es                     //声明使用WebGL2.0着色器
       uniform mat4 uMVPMatrix;            //总变换矩阵
       uniform mat4 uMMatrix;              //变换矩阵
       uniform vec3 uLightLocation;       //光源位置
       uniform vec3 uCamera;               //摄像机位置
       in vec3 aPosition;                  //顶点位置
       in vec3 aNormal;                    //顶点法向量
       out vec4 finalLight;                //传递给片元着色器的最终光照强度
       out float vFogFactor;               //传递给片元着色器的雾化因子
         ...//此处省略了计算光照的pointLight方法,读者可自行查看随书源代码
       float computeFogFactor(){          //计算雾化因子的方法
       float tmpFactor;                //定义雾化因子
       float fogDistance = length(uCamera-(uMMatrix*vec4(aPosition,1)).xyz);
       //顶点到摄像机的距离
       const float end = 450.0;       //雾结束位置
       const float start = 350.0;     //雾开始位置
       tmpFactor = max(min((end- fogDistance)/(end-start),1.0),0.0);
       //用雾公式计算雾化因子
            return tmpFactor;               //返回雾化因子
           }
       void main(){
            gl_Position = uMVPMatrix * vec4(aPosition,1);   //根据总变换矩阵计算此次绘制的
                  顶点位置
            finalLight = pointLight(normalize(aNormal), uLightLocation,
            vec4(0.4,0.4,0.4,1.0), vec4(0.7,0.7,0.7,1.0), vec4(0.3,0.3,0.3,1.0));
            //计算光照强度
            vFogFactor = computeFogFactor();                 //计算雾化因子
         }

片元着色器

 #version 300 es                           //声明使用WebGL2.0着色器
           precision mediump float;                  //给出默认的浮点精度
          in vec4 finalLight;                       //接收顶点着色器传过来的最终光照强度
          in float vFogFactor;                      //从顶点着色器传递过来的雾化因子
          out vec4 fragColor;                       //输出片元颜色
          void main(){
              vec4 objectColor=vec4(0.95,0.95,0.95,1.0);   //物体颜色
               vec4 fogColor = vec4(0.97,0.76,0.03,1.0);    //雾的颜色
              if(vFogFactor ! = 0.0){                        //如果雾化因子为0,不必计算光照
              objectColor = objectColor*finalLight;   //计算光照之后的物体颜色
                //物体颜色和雾颜色进行插值计算最终颜色
                fragColor = objectColor*vFogFactor + fogColor*(1.0-vFogFactor);
              }else{
                   //如果雾化因子为0,不必计算光照,不必加权,直接使用雾颜色作为片元颜色
                  fragColor=fogColor;
               }
           }

 实现非线性计算模型只需修改computeFogFactor

float computeFogFactor(){
             float tmpFactor;     //定义雾化因子
             float fogDistance = length(uCamera-(uMMatrix*vec4(aPosition,1)).xyz);
              //顶点到摄像机的距离
             const float end = 490.0;      //雾结束位置
             const float start = 350.0;    //雾开始位置
             tmpFactor = 1.0-smoothstep(start, end, fogDistance);  //计算雾化因子
             return tmpFactor;              //返回雾化因子
   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值