《OpenGL ES 3.x游戏开发(下卷)》一2.2 扭动的软糖

简介:

本节书摘来异步社区《OpenGL ES 3.x游戏开发(下卷)》一书中的第2章,第2.2节,作者: 吴亚峰 责编: 张涛,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.2 扭动的软糖

上一节介绍的飘扬的旗帜是对一个纹理矩形中的顶点位置进行了变换,本节的案例将对一个长方体中的顶点位置进行变换以实现软糖扭动的效果。

2.2.1 基本原理

介绍本案例的具体开发之前首先需要了解实现软糖扭动的基本原理,具体情况如图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_4_5
2_6_7

从图2-6与图2-7中可以看出,将顶点绕中心轴扭曲(旋转)实际上可以看成是将从中心点出发到变换前顶点的向量旋转指定的角度。旋转后得到的新向量的终点位置即所求的变换后顶点的位置,因此具体的计算公式如下。

x'=xcosα-zsinα    z'=xsinα+zcosα

说明

上述公式中的α为需要旋转(扭曲)的角度,实际计算时采用前面步骤计算出来的变量currAngle的值即可。

2.2.2 开发步骤

上一小节介绍了软糖扭动的基本原理,本小节将基于此原理开发一个软糖不断扭动的案例Sample2_2,其运行效果如图2-8所示。


2_8_1
2_8_2

说明

图2-8所示给出了4幅软糖扭动过程中的程序抓图,从左至右扭动角度不断增大。

了解了案例的运行效果后,接下来简要介绍本案例的具体开发过程。由于本案例中的大部分类和前面章节很多案例中的类非常相似,因此这里只给出本案例中比较有代表性的部分,具体内容介绍如下。

(1)首先需要简单说明的是,表示软糖的长方体类Cuboid,其大部分代码与本书前面的很多案例基本一致。主要区别是需要增加将当前帧最大扭动角度、y起始坐标、y坐标总跨度等数据传入渲染管线的相关代码,有了这些数据后顶点着色器在绘制每帧画面前就可以顺利地对顶点位置进行变换了。

提示

增加的代码非常简单,需要的读者请自行查阅随书。

(2)接着需要给出实现软糖扭动的顶点着色器,其代码如下。

1    #version 300 es
2    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坐标的代码。

相关文章
|
10月前
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
173 0
|
存储 编解码 算法
Opengl ES之LUT滤镜(上)
Opengl ES之连载系列
551 0
|
数据安全/隐私保护 开发者
OpenGL ES 多目标渲染(MRT)
Opengl ES连载系列
376 0
|
数据安全/隐私保护 索引
Opengl ES之纹理数组
Opengl ES连载系列
290 0
|
数据安全/隐私保护
Opengl ES之水印贴图
Opengl ES之连载系列
184 0
|
Java 数据安全/隐私保护 Android开发
Opengl ES之矩阵变换(下)
Opengl ES连载系列
183 0
|
Java API 数据安全/隐私保护
Opengl ES之矩阵变换(上)
Opengl ES连载系列
197 0
|
存储
Opengl ES之踩坑记
Opengl ES之连载系列
175 0
|
存储 编解码 算法
Opengl ES之RGB转NV21
Opengl ES连载系列
176 0
|
并行计算 C++
Opengl ES之YUV数据渲染
Opengl ES连载系列
206 0