iOS开辟学习OpenGL ES类别 -- 调换矩阵【彩民之家高

2019-10-13 04:21 来源:未知

  当然Babylon.js还援救更目迷五色的纹理类型,俺翻译了Babylon.js官方教程中关于反射与折射,反射探查,地图纹理,多种材料,动态纹理,高亮描边的文书档案(部分文书档案翻译的不显明,因为官方文书档案本身的发挥亦不是很明朗),能够在

原作地址:http://blog.csdn.net/liulong1567/article/details/50616523

举例:GLKMatrix4MakeRotation(GLKMathDegreesToRadians(60.0) , 1.0, 0.0, 0.0)会顺着三个特定的坐标系的X轴旋转60度来发出一个新的坐标系。

 1 //上下挤压,对于每个顶点都生效的变换尽量只执行一次
 2 function TranceRing1(arr)
 3 {
 4     var len=arr.length;
 5     for(var j=0;j<len;j  )
 6     {
 7         var obj=arr[j];
 8         if(obj.y<0)
 9         {
10             obj.y=obj.y/4;
11             if(obj.y<-1)
12             {
13                 obj.y=-1;
14             }
15         }
16         else if(obj.y>2)
17         {
18             obj.y=(obj.y-2)/2 2;
19         }
20     }
21     return arr;
22 }

退换矩阵

模型网格的三个维度空间地方都以由它们的终点坐标决定的,假使每一趟想要移动一下模型地方都要逐项改动各种网格的巅峰坐标,那将一件极其脑瓜疼的事,假诺蒙受须要出示动画效果那就更糟了。为了减轻这些难题,半数以上的三个维度系统都会提供调换操作,那些操作原理是完好移动网格,那样网格与世界坐标就有多少个针锋绝对调换,而不须求去改换每三个终极的坐标值。在这之中,转变操作富含:移动、旋转、缩放,这么些操作都以针对性网格全部相对世界坐标系的,并非特定的每四个极限。
图3-3中浮现了转移操作,图中有多个立方,每四个立方都以由一个立方网格组成,它们都富含同样的极端,在我们实行活动、旋转、缩放操作的时候没有需求改造那些极端的坐标值,而是给立方体网格赋予贰个调换操作。右侧暗绛红的立方体向右移动了4个单位(举办了[-4,0,0]操作),然后又相对x和y轴举行了旋转(这里注意一下,大家这里角度的单位是弧度,即一弧度等于360度除以2PI)。左侧土黄的立方体向右移动了4个单位,然后对四个趋势都加大了1.5倍,中间鲜绿立方体正是中期始地方。

彩民之家高手论坛 1

*
图3-3
大家用贰个矩阵来表示转变操作,这么些矩阵中保存着贰个数组,通过那一个数组实香港行政局地数学总计就能够赢得改造之后的终极坐标值。大多数的转变矩阵用44的数组表示,那么些数组包蕴4行4列一共十五个数。图3-4正是二个44数组的暗中提示图,当中m12、m13、m14用来操作移动,m0、m5、m10用来操作缩放,m1和m2、m4和m6、m8和m9分别用来操作相对x、y、z轴的转动,转换矩阵乘以顶点坐标便是改造之后的坐标。

彩民之家高手论坛 2

图3-4
假若您同小编同样是个线性代数极客,小编那样讲你早晚听得懂,假若您素不相识线性代数也没涉及,Unity3D以致别的工具中一度将那几个操作都卷入好了,大家只必要科学调用它们的API就能够,可是理解一下这么些操作的平底总结进程总依旧好的。

万一移动经过(1,0,0)的位移之后就为:(1 0.5 0 1),这正是大家地点看见的三角的上终点在显示器中间活动了。

  2、开首编写制定条带网格的门道(顶点数组),首先生成多个半径是7的圆形路线,规定圆弧由1二十五个极端组成(事实上最一生成的门路有1三十五个终端):

相对于平移和缩放,旋转要复杂一些。旋转包蕴五个至关首要因素,旋转的角度,绕什么轴转动。

  克隆路线和x轴平移的主意如下:

GLuint transformUniformLocation = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformUniformLocation, 1, 0, transformMatrix.m);

  规定船体沿x轴方向摆放,船体中央位于世界坐标系原点,船头朝向x轴负方向,船顶朝向y轴正方向。

GLKMatrix4 transformMatrix;

// 初始化为单位矩阵,不对图形产生任何变换
transformMatrix = GLKMatrix4Identity;

  实施效果如下:

OpenGL ES中的多种为主转移:平移(translation)、旋转(rotation)。基本转移的一路决定了在一个新的坐标系中的每叁个极限地方是怎么转变为参照坐标系中的一个岗位的。多少个基本转移足以产生持续坐标系。

彩民之家高手论坛 3

GLKit提供了GLKMatrix4MakeScale(float x,float y,float z)函数,这么些函数会通过扩充也许裁减四个单位矩阵的私下坐标轴的单位长度来回到一个定义了坐标系的矩阵。x、y和z参数钦点了用来扩展恐怕裁减各样轴的单位长度的元素。GLKMatrix4Scale(float x,float y,float z)函数通过按钦定的因子缩放作为参数字传送入矩阵来回到二个定义了坐标系的新矩阵。

 1 //用一个重合点路径封口
 2 function MakePointPath(vec,size)
 3 {
 4     var arr_point=[];
 5     for(var i=0;i<size;i  )
 6     {
 7         arr_point.push(vec.clone());
 8     }
 9     return arr_point;
10 }
GLKMatrix4 rotateMatrix = GLKMatrix4MakeRotation(elValue , 0.0, 0.0, 1.0);
// 绕Z轴旋转

  首先将从左边看船头上部的中等截面通过将x坐标除以(5/3.25)的不二秘技调换为正圆的一部分,用(-10-obj.x)/(5/3.25)计算出“xsize”的长度,因为y轴缩放比例特别在此个截面上顶峰中度(y值)和半径(r)的比等于sin(a),所以只须求出角a的深浅就能够算出比例,而角a的深浅能够由(xsize/r)的反余弦得出。如此得出y方向的缩放比例。

彩民之家高手论坛 4

  这里的arr7是投身同贰个岗位的1三十多少个终端,用来给敞开的船尾封口(使用多余的终极算是条带网格模型的三个毛病,但以此毛病和条带网格的易用性比起来尚可)至于船首的封口则由末端的网格调换负担。

// 缩放
GLKMatrix4 scaleMatrix = GLKMatrix4MakeScale(elValue, elValue, 1.0);

// 旋转
GLKMatrix4 rotateMatrix = GLKMatrix4MakeRotation(elValue , 0.0, 0.0, 1.0);

// 平移
GLKMatrix4 translateMatrix = GLKMatrix4MakeTranslation(elValue, elValue, 0.0);

/*
transformMatrix = translateMatrix * rotateMatrix * scaleMatrix
矩阵会按照从右到左的顺序应用到position上。也就是先缩放(scale),再旋转(rotate),最后平移(translate)
如果这个顺序反过来,就完全不同了。从线性代数角度来讲,就是矩阵A乘以矩阵B不等于矩阵B乘以矩阵A。
*/
transformMatrix = GLKMatrix4Multiply(translateMatrix, rotateMatrix);
transformMatrix = GLKMatrix4Multiply(transformMatrix, scaleMatrix);

 

看一下尾声效果:

彩民之家高手论坛 5

修改代码,看一下GLKit提供的GLKMatrix4MakeTranslation函数完结活动效果。

  随后编写二个格局让机翼前倾斜,距机身越远的极限向后移动的离开越大。

各种核心转移对应于矩阵的一个粗略变化。定义贰个与参考坐标系同样的坐标系的矩阵叫做单位矩阵。跋扈三个矩阵能够在三个联级(又叫矩阵乘法)操作中结合起来以发生叁个新矩阵,这一个新矩阵富含了八个矩阵的富有转换。实际上,每在那之中央转移会产生贰个轻巧的矩阵,然后把那一个大约的矩阵与当下转变矩阵连接起来以发生一个新的当前矩阵。

彩民之家高手论坛 6

彩民之家高手论坛 7

  这里的算法很简短,遍历路径中的每种终端,然后遵照上边的宏图举办逻辑决断就可以。

本例代码:LearningOpenGL ES GitHub

  接下去使用“var arr1=TranceRing1(MakeRing(7,128));”将圆形路线变成我们规划的船体截面路线,TranceRing1艺术代码如下:

彩民之家高手论坛 8

  用分化的比重对路径举办削减,将本来尺寸同样的门道形成尺寸渐变的门道,路径连成的条带网格就能够显现椎体的模样,那么难点就在于如何总计这一个缩放的比重,使得椎体的外表展现为狡滑的圆弧。

从数学上说,转变就是在八个坐标系之间转变顶点坐标。种种坐标系都是相持于任何的仿效坐标系定义的。对于OpenGL ES来讲,最后的参阅坐标系是在三个像素颜色渲染缓存中的像素地点的2D数组。

  然后初阶创设贰个相符上述轮廓的条带网格。

概念全局

 1 //克隆复制对象数组
 2     function CloneArrPoint(arr)
 3     {
 4         var arr2=[];
 5         var len=arr.length;
 6         for(var i=0;i<len;i  )
 7         {
 8             arr2.push(arr[i].clone());
 9         }
10         return arr2;
11     }
12     //平移x轴
13     function MoveX(path,dis)
14     {
15         var len=path.length;
16         for(var i=0;i<len;i  )
17         {
18             path[i].x =dis;
19         }
20         return path;
21     }
attribute vec4 position;
attribute vec4 color;
varying vec4 fColor;
uniform mat4 transform;
void main(void) {
    fColor = color;
    gl_Position = transform * position;
}
1 mat_blue.twoSidedLighting=true;//双面光照选项

彩民之家高手论坛 9

  想象翼面在y方向由多层相互重叠的构造组成,每一片的尺码差异,由此页面能够有所两重的圆弧边缘,暗暗表示图如下:

缩放
缩放是通过相对于参谋坐标系的坐标轴的单位长度退换新坐标系的坐标轴的单位长度来定义一个新坐标系。缩放坐标系与参照他事他说加以考察坐标系使用同一个原点。坐标轴的样子普通不会转移。不过,通过二个负值所做的缩放就能翻转坐标轴的主旋律。

  使用上一篇小说(  

至于旋转矩阵可以参见那篇三个维度空间中的旋转:旋转矩阵、欧拉角

  遵照规划,从最上部俯视船体的前半有的是叁个z向半径为7、x向半径为15的“圆弧形”,从左边看船头的上部是y向半径为3.25、x向半径为5的圆弧形,船头的下面是y向半径为1、x向半径为2的圆弧形。

// 绕x轴
    transformMatrix = GLKMatrix4Make(1.0, 0.0,           0.0,          0.0,
                                     0.0, cos(elValue), -sin(elValue), 0.0,
                                     0.0, sin(elValue),  cos(elValue), 0.0,
                                     0.0, 0.0,           0.0,          1.0);

    // 绕y轴
    transformMatrix = GLKMatrix4Make(cos(elValue),0.0, sin(elValue), 0.0,
                                     0.0,         1.0, 0.0,          0.0,
                                    -sin(elValue),0.0, cos(elValue), 0.0,
                                     0.0,         0.0, 0.0,          1.0);

    // 绕z轴
    transformMatrix = GLKMatrix4Make(cos(elValue),-sin(elValue), 0.0, 0.0,
                                     sin(elValue), cos(elValue), 0.0, 0.0,
                                     0.0,           0.0,         1.0, 0.0,
                                     0.0,           0.0,         0.0, 1.0);

  事实上,在编排3D模型时平素的长短数值并未有决定性的意义(当然过大或过小莫不引致实体脱出视场),决定模型形状的显借使处处尺寸之间的百分比关系,具体的尺寸大小都能够在载入模型后遵照要求开展缩放,这里将船体长度设为30单位是为了在预设的编排场景里方便查看。

看下最终富含了运动、缩放、旋转的法力:

  5、通过极端转变生成锥形的船头:

彩民之家高手论坛 10

  6、生成都飞机船的后掠翼,生成规律与船首类似:

至于OpenGL ES的三种基本转移就谈到那边,其实还应该有三个基本点的投影转换 -- 透视投影和正交易投资影。就不在本篇继续说了,尽量调控一下篇幅,就在下一篇讲啊!

  缩放后的来得效果如下:

上面结合二种转移,直接相乘就足以,可是要静心顺序:平移旋转缩放。那样能够有限援助先缩放,再旋转,最终平移。

  尾翼的变动方式和品位翼相似。

接下去在利用中开创多少个平移调换矩阵:

  笔者将圆弧定义为拉伸的正圆形的一有个别,然后由x坐标值总括出对应路线的缩放比例,原理图如下(以“从左边看的船首上部”为例):

彩民之家高手论坛 11

  附实际开垦时利用的草图:

因为我们只是挪动了坐标X值,Y和Z值未有变,所以三角形只是沿着X轴平行移动。

彩民之家高手论坛 12

把这一个调换矩阵赋值到uniform mat4 transform上:

  4、使用上一篇小说中涉嫌的方式生成条带网格:

因为我们的数额更新在update里,而赋值绘制在glkView:(GLKView *)view drawInRect:(CGRect)rect中,所以供给定义为大局:

   然后参照他事他说加以考察上海体育地方,在多个短轴为w长轴为h的拉伸扇形中计算各个终端向左或右边手的偏移量。

假若依旧点(0.0,0.5,0.0)的x和y值在减少0.5从此为(0.0,0.25,0.0),看下矩阵总括:

彩民之家高手论坛 13

透过上边的矩阵总结能够开掘,平移矩阵便是在二个4x4的转移矩阵中填充第4行前边七个职位:

  计算y、z坐标的暗暗提示图如下:

GLKMatrix4 scaleMatrix = GLKMatrix4MakeScale(elValue, elValue, 1.0);
// 很明显这个矩阵会改变顶点坐标的x、y值

彩民之家高手论坛 14

旋转
旋转是由此相对于仿效坐标系坐标轴的趋势旋转新坐标系的坐标轴来定义叁个新坐标系。旋转的坐标系会与参谋坐标系使用同八个原点。旋转不会影响坐标轴的单位长度,唯有坐标轴的动向会产生变化。

  1、从顶上部分看,推测飞船的源流长度为30单位,船体最宽处半径为7单位,船头处呈油滑的锥形;从船头方向看,船体最上端为较扁的圆弧,船尾部边缘狡滑中间平直(有一点点像上个世纪的航天飞机)。草图如下:

彩民之家高手论坛 15

  7、在调整台实施ChangeMaterial(mesh_origin,mat_blue)能够将材料转化为纯月光蓝,因为条带网格的法线方向暗许指向飞船内部,那时飞船外界将不可能显得光照的镜面反射效用,化解办法是在开端化材料时设置:

上面的elValue值域为[-1,1],先看一下为-1的时候,我们取中间三个终端(0,0.5,0)经过(-1,0,0)的移位之后为(-1,0.5,0),大家看一下矩阵计算:

  路线克隆的暗暗提示图如下:

这里的GLKMatrix4Identity也就是下边包车型大巴矩阵:

彩民之家高手论坛 16

绘图之后看下效果:

彩民之家高手论坛 17

简单易行解析:elValue为正弦函数的值,所以在-1和1以内,在elValue为1是,不会对原数据有震慑,当为-1时,就能翻转坐标轴的自由化。所以最终效果就是上海教室那样,从原图裁减到0,然后负数增大,便是倒过来了。

  MakePointPath代码如下:

GLKit提供了GLKMatrix4MakeRotation(float angleRedians, float x, float y, float z)函数,那一个函数通过旋转五个单位矩阵来回到一个概念了坐标系的新矩阵。angleRedians参数指定了要旋转的弧度数。使用GLKMathDegreesToRadians(float degrees)函数能够把角度调换到弧度。x、y和z参数用于钦命当前坐标系的哪一个轴作为旋转的轮毂。

  对于船体上部,中度低于2的片段直接运用半径为7的弧形作为仓壁,高于2的一对则将中度降低八分之四;对于船体下部,将大意形状设为压扁到五分二的圆弧,再将高度低于-1的部分设为平直的船底。

// 定义一个在值域-1和1之间的局部变量
GLfloat elValue = sinf(changeValue);

// 创建平移变换矩阵,这里只改变了X坐标
GLKMatrix4 translateMatrix = 
GLKMatrix4MakeTranslation(elValue, 0.0, 0.0);

  侧边暗中表示图如下:

彩民之家高手论坛 18

  船首的变形代码如下:

除去选拔GL基特提供的GLKMatrix4MakeRotation函数直接扭转,我们还足以友善定义4x4的旋转矩阵:

 1 //有的顶点变换会受到周围顶点的影响,所以要在已经构造好的基础上进行变换
 2 function TransCraft()
 3 {
 4     var len=arr_path.length;
 5     //遍历每个点,用程序判断这个点是否符合某些标准,并进行相应变化
 6     for(var i=0;i<len;i  )
 7     {
 8         var arr_point=arr_path[i];
 9         var len2=arr_point.length;
10         for(var j=0;j<len2;j  )
11         {
12             var obj=arr_point[j];
13             //var x=obj.x;
14             //var y=obj.y;
15             //var z=obj.z;
16             //船首呈椎体状
17             if(obj.x<-13&&obj.y<0)//从侧面看的船首下部
18             {
19                 var rate=Math.sin(Math.acos((-13-obj.x)/2/1));//y轴方向缩放系数
20                 obj.y=obj.y*rate;
21             }
22             if(obj.x<-10&&obj.y>0)//从侧面看的船首上部
23             {
24                 var rate=Math.sin(Math.acos((-10-obj.x)/(5/3.25)/3.25));//y轴方向缩放系数
25                 obj.y=obj.y*rate;
26             }
27             if(obj.x<0)//从顶部看的船首
28             {
29                 var rate=Math.sin(Math.acos((-obj.x)/(15/7)/7));//y轴方向缩放系数
30                 obj.z=obj.z*rate;
31             }

平移
经过相对于参谋坐标系的原点移动新坐标系的原点、平移定义了二个新的坐标系。平移不会潜濡默化坐标轴的单位长度,平移不会变动坐标轴相对于参考坐标系的矛头。
GLKit提供了GLKMatrix4MakeTranslation(float x,float y,float z)函数,这么些函数通过运动五个单位矩阵来回到叁个概念了坐标系的新矩阵。x、y、z参数内定了新坐标原点沿着当前参见坐标系的各类轴移动的单位数。

1 var arr7=MakePointPath(new BABYLON.Vector3(15,0,0),129);//用一个点封口
2     arr_path.push(arr7);
3 
4     mesh_origin=BABYLON.MeshBuilder.CreateRibbon("mesh_origin",{pathArray:arr_path
5         ,updatable:true,closePath:false,closeArray:false});
6     mesh_origin.material=mat_frame;

看下效果图:

  3、将下不熟习成的一条门路克隆为多条路子,规定每两条路子之间的间距为0.25:

在极端着色器中新扩展了二个uniform mat4 transform。 mat4这么些种类前文有涉嫌过,4X4的矩阵。它是Shader内置的门类,协理间接加减乘等操作。使用矩阵会爆发越来越少的演算指令,GPU能够越来越好的优化运算进程。

  感到翼面由多层组成,参谋下图,最大的一层宽度为7.5,最小的一层宽度为6.5,此中某一层与纤维层的大幅差为size1,使用和船头圆弧类似的秘技算出size1的值,进而算出这一层的尺码。

彩民之家高手论坛 19

  y和z的测算要求采取初级中学数学的三角形函数知识。

1 arr_path=[];//路径数组
2     var xstartl=-15;//设置船头(也就是第一个圆环路径)在x轴上的位置    
3     var arr1=TranceRing1(MakeRing(7,128));
4     for(var i=0;i<121;i  )
5     {
6         var arr_point=CloneArrPoint(arr1);//克隆一条路径
7         arr_path.push(MoveX(arr_point,i*0.25 xstartl));//将克隆出的路径沿x轴方向平移
8     }

  

  从顶端看的缩放比例也是这样计算,那时计算获得的是z轴方向的缩放比例。

 1 //后掠翼,具有圆弧状的边缘
 2             if(obj.x>0&&obj.y>0&&obj.y<1)
 3             {
 4                 //这一层翼面和最小翼面的边缘差值
 5                 var rate=Math.cos(Math.asin(Math.abs(0.5-obj.y)/(0.5/1)/1));
 6                 var size1=1*rate;
 7                 var h=14 size1;
 8                 var w=6.5 size1;
 9                 if((15-obj.x)<h)
10                 {
11                     var rate2=Math.cos(Math.asin(Math.abs(15-obj.x)/(h/w)/w));
12                     if(obj.z>0)
13                     {
14                         obj.z =w*rate2;
15                     }
16                     else if(obj.z<0)
17                     {
18                         obj.z-=w*rate2;
19                     }
20                     var rate3=3/(15-Math.abs(obj.z))
21                     obj.x =rate3;
22                 }
23 
24             }

 

  大家率先对3D模型的概貌进行评估价值,然后创造三个具有丰硕多终端的、与模型轮廓近似的网格对象(这里选用条带类网格对象),接着对网格的一部分极端进行岗位转变以发出模型的细节,最后为模型设置二个质地。

    

彩民之家高手论坛 20

  执行ChangeMaterial(mesh_origin,mat_阿尔法)可以将材料转化为半透明,同样须要对mat_阿尔法设置上述天性,不然将独有飞船的内表面可以预知,半晶莹剔透效果如下图:

 1 function MakeRing(radius,sumpoint)//两个参数分别是圆形的半径和圆形由多少个顶点组成
 2     {
 3         var arr_point=[];//顶点数组
 4         var radp=Math.PI*2/sumpoint;//每一个顶点在圆弧上转过的角度
 5         for(var i=0.0;i<sumpoint;i  )
 6         {
 7             var x=0;
 8             var rad=radp*i;
 9         //算出顶点的y、z坐标
10             var y=radius*Math.sin(rad);
11             var z=radius*Math.cos(rad);
12             arr_point.push(new BABYLON.Vector3(x,y,z));
13         }
14         arr_point.push(arr_point[0].clone());//为了保持首尾相连,要再添加一次第一个顶点
15         return arr_point;
16     }

彩民之家高手论坛 21 

 

  生成的概貌网格如下图:

  能够观察船头的1贰15个极点被缩放到了扳平地点,船头显示油滑的弧线。

版权声明:本文由彩民之家高手论坛发布于前端知识,转载请注明出处:iOS开辟学习OpenGL ES类别 -- 调换矩阵【彩民之家高