- 1. demo概述
- 2. 实现过程
- 2.1 模型的旋转操作
- 2.2 模型的缩放操作
- 2.3 模型的平移操作
- 3. demo 代码
在之前的一篇文章中讲述了,二维空间中物体的基本变换,即旋转、缩放、平移,现在学习一下三维空间下的基本变换,思路与原理是一样的,只不过是由二维提升为三维, 关于三维场景下的基本变换,请参照这篇文章图形学中的基本变换中的三维图形的基本变换部分
2. 实现过程 2.1 模型的旋转操作分别绕X轴旋转,Y轴旋转,Z轴旋转的矩阵如下
//绕z轴旋转矩阵
mat4 rotZ(float a) {
return mat4(cos(a),-sin(a),0.0,0.0,
sin(a),cos(a),0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
);
}
//绕x轴旋转矩阵
mat4 rotX(float a) {
return mat4(1.0,0.0,0.0,0.0,
0.0,cos(a),-sin(a),0.0,
0.0,sin(a),cos(a),0.0,
0.0,0.0,0.0,1.0
);
}
//绕y轴旋转矩阵
mat4 rotY(float a) {
return mat4(cos(a),0.0,sin(a),0.0,
0.0,1.0,0.0,0.0,
-sin(a),0.0,cos(a),0.0,
0.0,0.0,0.0,1.0
);
}
调用过程
我们在计算交点距离和材质的函数中,完成变换过程,首先绘制了一个用来对比的box0,然后设置一个变换方块自己的屏幕坐标,对这个坐标左乘对应的变换矩阵,之后拿变换后的屏幕坐标绘制想要绘制的方块即可,具体如下
vec2 getDistandMaterial(vec3 p){
float plane = p.y;//地面
vec2 res = vec2(plane,0.0);
//未变换前的立方体
vec2 box0 = vec2(sdBox(p-vec3(-1.5,2,5),vec3(0.6),0.06),1.0);//原方块,材质ID为1.0
vec3 pos = p-vec3(1.5,2,5);//确定模型的中心
vec4 boxPos = vec4(pos,1.0);//转为其次坐标
boxPos*=rotX(u_time);
boxPos*=rotY(u_time);
boxPos*=rotZ(u_time);
vec2 box = vec2(sdBox(boxPos.xyz,vec3(0.6),0.06),2.0);//变换方块,材质ID为2.0
res = opU(res,box0);
res = opU(res,box);
return res;
}
执行结果如下,是一张静态图,左侧蓝色方块为为变换的方块,右侧的橙色方块是经过变换的方块,实际运行结果是橙色方块不断的绕三轴旋转
获取缩放矩阵的函数
//缩放矩阵
mat4 scaled(vec3 scale){
//缩放矩阵作用于坐标系,所以放大和缩小刚好相反,为了使用习惯,缩放参数取倒数
return mat4(1.0/scale.x,0.0,0.0,0.0,
0.0,1.0/scale.y,0.0,0.0,
0.0,0.0,1.0/scale.z,0.0,
0.0,0.0,0.0,1.0
);
}
调用过程
vec3 scale = vec3(1.2,1.5,2.0);//确定缩放倍数 boxPos *= scaled(scale); vec2 box = vec2(sdBox(boxPos.xyz,vec3(0.6),0.06),2.0);//变换方块,材质ID为2.0
执行结果
补充
三维空间中的缩放与二维空间中的缩放一样,也可给坐标相乘或相除一个数值来实现模型的缩放
例如如下代码会使模型在x轴方向缩小两倍,在y轴方向放大1.5倍
boxPos.x *= 2.0;//x轴方向缩小两倍 boxPos.y /= 1.5;//y轴方向放大1.5倍2.3 模型的平移操作
平移矩阵实现
//平移矩阵
mat4 translation3d(vec3 translate){
//平移矩阵作用于坐标系,所以平移的方向相反,为了使用习惯,缩放参数取负
return mat4(1.0,0.0,0.0,-translate.x,
0.0,1.0,0.0,-translate.y,
0.0,0.0,1.0,-translate.z,
0.0,0.0,0.0,1.0
);
}
调用过程
平移的调用过程与前两种变换不太一样,为了作为参照,需要在变换前把执行平移变换方块的坐标移动到参考方块坐标的位置,然后进行平移变换,具体如下
pos = p-vec3(-1.5,2,5);//平移前将橙色方块移到与蓝色方块重合位置 boxPos = vec4(pos,1.0);//转为其次坐标 vec3 trans = vec3(2.0,1.8,0.2);//确定沿xyz轴的平移距离 boxPos *= translation3d(trans); vec2 box = vec2(sdBox(boxPos.xyz,vec3(0.6),0.06),2.0);//变换方块,材质ID为2.0
执行结果
补充
与二维空间中的平移一样,也可给坐标相加或相减一个数值来实现模型的平移
例如如下代码会使模型沿x轴右移2个单位,沿y轴上移1.8个单位
boxPos.x -= 2.0;//右移2个单位 boxPos.y -= 1.8;//上移1.8个单3. demo 代码
今天的代码是在上一篇文章的基础上添加的内容,实际新增的内容并不多,不过还是老规矩,贴上全部代码



