本文共 2164 字,大约阅读时间需要 7 分钟。
本节书摘来异步社区《OpenGL ES 3.x游戏开发(下卷)》一书中的第2章,第2.2节,作者: 吴亚峰 责编: 张涛,更多章节内容可以访问云栖社区“异步社区”公众号查看。
上一节介绍的飘扬的旗帜是对一个纹理矩形中的顶点位置进行了变换,本节的案例将对一个长方体中的顶点位置进行变换以实现软糖扭动的效果。
介绍本案例的具体开发之前首先需要了解实现软糖扭动的基本原理,具体情况如图2-4所示。
从图2-4中可以看出,软糖模型实际上是由很多层小矩形叠加而成。在同一帧中,随着y坐标的不断升高,此层的顶点绕中心轴扭曲的角度越大。因此,实现扭动软糖的效果只要将代表软糖的长方体中各层顶点的x、z坐标按照一定的规则根据顶点的y坐标以及当前帧的控制参数进行变换即可,具体的计算思路如图2-5、图2-6与图2-7所示。
具体的计算步骤如下。
首先如图2-5所示,需要计算出当前顶点y坐标与最下层顶点y坐标的差值。
接着根据y坐标的差值、角度换算比例以及本帧的总扭曲角度换算出当前顶点的扭曲角度,计算公式为:currAngle =(currY-yStart)/ySpan×angleSpan。最后根据当前顶点的x、z坐标以及扭曲的角度计算出变换后顶点的x、z坐标,此步的计算思路如图2-6与图2-7所示。从图2-6与图2-7中可以看出,将顶点绕中心轴扭曲(旋转)实际上可以看成是将从中心点出发到变换前顶点的向量旋转指定的角度。旋转后得到的新向量的终点位置即所求的变换后顶点的位置,因此具体的计算公式如下。
x'=xcosα-zsinα z'=xsinα+zcosα
说明
上述公式中的α为需要旋转(扭曲)的角度,实际计算时采用前面步骤计算出来的变量currAngle的值即可。
上一小节介绍了软糖扭动的基本原理,本小节将基于此原理开发一个软糖不断扭动的案例Sample2_2,其运行效果如图2-8所示。
说明
图2-8所示给出了4幅软糖扭动过程中的程序抓图,从左至右扭动角度不断增大。
了解了案例的运行效果后,接下来简要介绍本案例的具体开发过程。由于本案例中的大部分类和前面章节很多案例中的类非常相似,因此这里只给出本案例中比较有代表性的部分,具体内容介绍如下。
(1)首先需要简单说明的是,表示软糖的长方体类Cuboid,其大部分代码与本书前面的很多案例基本一致。主要区别是需要增加将当前帧最大扭动角度、y起始坐标、y坐标总跨度等数据传入渲染管线的相关代码,有了这些数据后顶点着色器在绘制每帧画面前就可以顺利地对顶点位置进行变换了。
提示
增加的代码非常简单,需要的读者请自行查阅随书。
(2)接着需要给出实现软糖扭动的顶点着色器,其代码如下。
1 #version 300 es2 uniform mat4 uMVPMatrix; //总变换矩阵3 in vec3 aPosition; //顶点位置4 in vec2 aTexCoor; //顶点纹理坐标5 out vec2 vTextureCoord; //用于传递给片元着色器的纹理坐标6 uniform float angleSpan; //本帧扭曲总角度7 uniform float yStart; //y坐标起始点8 uniform float ySpan; //y坐标总跨度9 void main(){10 float tempAS= angleSpan*(aPosition.y-yStart)/ySpan; //计算当前顶点扭动(绕中心点选择)的角度11 vec3 tPosition=aPosition;12 if(aPosition.y>yStart){ //若不是最下面一层的顶点则计算扭动后的x、z坐标13 tPosition.x=(cos(tempAS)*aPosition.x-sin(tempAS)*aPosition.z);14 tPosition.z=(sin(tempAS)*aPosition.x+cos(tempAS)*aPosition.z);15 }16 gl_Position = uMVPMatrix * vec4(tPosition,1); //根据总变换矩阵计算此次绘制此顶点的位置17 vTextureCoord = aTexCoor; //将接收的纹理坐标传递给片元着色器18 }
说明
上述顶点着色器根据上一小节介绍的计算过程实现了对顶点位置的变换,其中最核心的就是第13~第14行根据扭动角度计算变换后顶点x、z坐标的代码。
转载地址:http://ovsxa.baihongyu.com/