OpenGL ES 2.0游戏开发(下卷)
上QQ阅读APP看书,第一时间看更新

3.3 色散效果的模拟

上一小节通过玻璃球实现放大镜效果的案例介绍了折射效果的开发,读者应该觉得案例的整体效果还是非常逼真的。但还有一点不够真实的地方,那就是现实世界中不同颜色的光对于同一种材质的折射率是不完全相同的。因此,透过玻璃球观察现实世界时会产生色散的效果。本节将通过一个案例Sample3_3向读者介绍如何基于OpenGL ES 2.0来开发折射时色散的效果。

3.3.1 案例效果与基本原理

介绍本案例的具体开发步骤之前,首先需要了解一下案例的运行效果与基本原理,其运行效果如图3-6所示。

▲图3-6 折射色散案例运行效果图

从运行效果图中可以看出,本案例场景基本上与上一节的案例相同,唯一不同的就是在透过玻璃球观察后面的场景时不但会有放大镜的效果,物体的边缘还会有彩虹一样的条纹出现,这就是色散现象。

提示

由于本书是黑白灰度印刷,因此通过上面的图3-10可能看不到色散的效果,这时请读者自行运行本节的案例或参看本书前面的彩页。

前面已经简单提过,色散的原因是不同颜色的光对于同一种材质的折射率不完全相同。这就是说一束由不同颜色的光组成的光线经过折射后,不同颜色的组成部分出射方向会有发散,形成彩虹一样的效果,图3-7很好地说明了这个问题。

▲图3-7 折射色散的原理

提示

了解了色散的基本原理与案例的运行效果后,下面就可以进行实际的开发了,下一小节将对这些内容进行介绍。

3.3.2 开发步骤

由于本案例与上一节案例的大部分代码相同,仅仅片元着色器有所不同。因此,这里仅给出改动后片元着色器的代码,具体内容如下。

代码位置:见随书光盘中源代码/第3章/Sample3_3/assets目录下的frag_tex_cube.sh。

      1    precision mediump float;
      2    uniform samplerCube sTexture;  //纹理内容数据
      3    varying vec3 eyeVary;           //接收从顶点着色器过来的视线向量
      4    varying vec3 newNormalVary;    //接收从顶点着色器过来的变换后法向量
      5    vec4 zs(                      //根据法向量、视线向量及斯涅尔定律计算立方图纹理采样的方法
      6      in float zsl                  //折射率
      7  ){
      8      vec3 vTextureCoord=refract(-eyeVary,newNormalVary,zsl);//根据斯涅尔定律计算折射
      9      vec4 finalColor=textureCube(sTexture, vTextureCoord);  //进行立方图纹理采样
      10     return finalColor;
      11   }
      12   void main(){
      13      vec4 finalColor=vec4(0.0,0.0,0.0,0.0);
      14      //由于有色散RGB 3个色彩通道单独计算折射
      15      finalColor.r=zs(0.97).r;     //计算红色通道的采样结果
      16      finalColor.g=zs(0.955).g;    //计算绿色通道的采样结果
      17      finalColor.b=zs(0.94).b;     //计算蓝色通道的采样结果
      18      gl_FragColor=finalColor;     //将最终片元颜色传递给管线
      19   }

提示

从上述代码中可以看出,大部分代码都没有变化,只是第15-17行将不同颜色的光分量以不同的折射系数单独进行了折射计算。

到这里为止如何实现折射色散效果的模拟就介绍完了,在以后的具体项目开发中读者若能做到灵活运用,将可以开发出更加逼真的场景。