本节书摘来自异步社区《android 应用案例开发大全(第3版)》一书中的第2章,第2.8节壁纸中的着色器开发,作者 吴亚峰 , 苏亚光 , 于复兴,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.8 壁纸中的着色器开发
前面已经对3d动态壁纸——百纳水族馆的相关类进行了简要的介绍。本节将对本案例中用到的相关着色器进行介绍。本案例中用到的着色器共有四对,即气泡着色器、背景着色器、鱼类着色器及珍珠贝着色器。下面就对本壁纸中用到的着色器的开发进行一一介绍。
2.8.1 气泡的着色器
气泡着色器分为顶点着色器与片元着色器,下面便分别对气泡着色器的顶点着色器和片元着色器的开发进行详细介绍。
(1)首先介绍的是气泡着色器中的顶点着色器的开发,其详细代码如下。
第1~4行是着色器中接收数据传递数据的声明。接收java代码部分的总变换矩阵、顶点位置及顶点纹理坐标。并将顶点纹理坐标从顶点着色器传递到片元着色器中。
第5~8行该顶点着色器的主要作用就是根据java传递过来的模型本身的顶点位置aposition与总变换矩阵计算出gl_position,每顶点执行一次。
(2)完成顶点着色器的开发后,下面开发的是气泡的片元着色器,其详细代码如下。
第1~7行该片元着色器的作用主要为根据从顶点着色器传递过来的纹理坐标数据vtexturecoord和从java代码部分传递过来的stexture计算片元的最终颜色值,并将最终颜色值赋值给着色器内建输出变量gl_fragcolor,每片元执行一次。
说明
因为背景的着色器代码与上述气泡着色器的代码基本一致,故在此不再详细介绍背景的着色器。读者可自行查看随书光盘中的源代码,其位置在项目目录assets/shader/目录下的back_vertex.sh与back_frag.sh。
2.8.2 珍珠贝的着色器
前面已经为读者介绍了珍珠贝模型的加载方法,但仅是一个带骨骼动画的珍珠贝,并不能使用户感觉真实,因为现实世界中是有阳光的,所以,我们用着色器给珍珠贝增加了灯光,这样就会出现水族馆中真实感超强的珍珠贝。下面对珍珠贝的着色器进行详细的介绍,其具体代码如下。
(1)首先介绍的是珍珠贝着色器中的顶点着色器的开发,具体代码如下。
第1~11行是顶点着色器中全局变量的声明,相比于气泡的顶点着色器,它主要增加了变化矩阵、光源位置、摄像机位置以及顶点法向量的引用。此处还声明了传递给片元着色器3种通道光的变量,分别是环境光变量、散射光变量、镜面反射光变量。
第13~38行是计算光照的3种光的最终强度。首先直接计算出环境光最终强度,其中最重要的是在进行计算前要对顶点法向量进行变换,将法向量变换到当前的姿态下。然后计算各种所需数据,最后计算出镜面光和镜面反射光的最终强度。
第40~48行是顶点着色器的main方法,其中首先调用了pointlight方法将3种通道光的强度值传递给片元着色器,并将接收到的顶点纹理坐标传递给片元着色器,以供片元着色器计算每片片元的最后颜色值。
(2)之前介绍了珍珠贝顶点着色器的开发,下面为读者详细介绍珍珠贝着色器中片元着色器的开发。其详细代码如下。
第1~12行是珍珠贝着色器中片元着色器的代码。它根据从顶点着色器传递过来的顶点纹理坐标,对java代码部分传递过来的片元颜色值进行采样,并且接收顶点着色器传递过来的3个通道光值,计算出片元的最终颜色值,然后再将其传递给渲染管线。
2.8.3 鱼类的着色器
前面已为读者介绍了鱼类模型加载。单纯的一个鱼类的骨骼动画并不能使水族馆看起来真实,所以前面已为鱼类着色器传递了一张明暗纹理图为此做准备。在鱼类着色器中,我们为鱼类添加了灯光,并为鱼类本身采取了多重纹理采样绘制。
(1)首先介绍的是鱼类的顶点着色器,由于本着色器中对鱼类灯光的设置与上节中对珍珠贝的灯光设置一致,故不再赘述,请读者自行查看随书光盘中的源代码。本小节将着重介绍对多重纹理采样绘制的实现。其具体代码如下。
第1~13行是着色器中对全局变量的声明,主要包括总变换矩阵、变换矩阵、光源位置、摄像机位置、顶点位置以及顶点法向量的引用等,还有对传递给片元着色器的相关变量声明。
第19~21行是对java代码部分传递过来的顶点法向量进行计算。对法向量进行变换,将法向量变换到当前的姿态下,并传递给片元着色器。
第22~23行将java代码部分传递过来的顶点纹理坐标传递给片元着色器,然后根据鱼类本身的顶点计算出顶点在物理世界的坐标并传递到片元着色器。
(2)介绍完鱼类的顶点着色器后,下面将介绍鱼类的片元着色器,此片元着色器实现了鱼类身体上的明暗效果与灯光特效。下面着重介绍明暗效果的实现,其具体代码如下所示。
第1~9行接收java代码部分传过来的鱼类本身纹理内容数据和鱼类明暗采样纹理内容数据,接收顶点着色器传递过来的法向量、顶点数据与环境光、散射光、镜面反射光及顶点纹理坐标数据,用于片元着色器对每一片元颜色的计算。
第11~16行首先声明一个浮点数变量f,再声明3个用于采样颜色存储的浮点数向量。然后根据鱼类模型的顶点在物理世界中的坐标,计算出在88明暗采样纹理图中对应的顶点纹理坐标s、t,为后面的采样颜色值做准备。
第17~33行根据顶点着色器传递过来的顶点法向量计算出明暗纹理的采样颜色值。当然鱼类不能全身都有明暗,因此根据其法向量规定大于0.2的为全部纹理明暗采样颜色值,在0.2~0.2之间将明暗采样颜色值从1逐渐降为0,使之平滑过渡,小于0.2取采样值为0。然后计算出混合后的颜色值,再综合3个通道光计算出片元的最终颜色值,送入渲染管线。