地区网站建设,天眼查官网查询企业,泰安千橙网络科技有限公司,在线购物网站旋转
1 #xff09;旋转的概念
三维物体的旋转要比位移复杂一点#xff0c;三维物体的旋转需要满足以下条件#xff1a; 旋转轴旋转方向旋转角度 场景举例 模型站在旋转轴的起点进行旋转模型要往左转还是往右转#xff0c;就是旋转的方向模型旋转的大小就是旋转角度 2 旋转的概念
三维物体的旋转要比位移复杂一点三维物体的旋转需要满足以下条件 旋转轴旋转方向旋转角度 场景举例 模型站在旋转轴的起点进行旋转模型要往左转还是往右转就是旋转的方向模型旋转的大小就是旋转角度 2 旋转方向的正负
在webgl中除裁剪空间之外的大部分功能都使用了右手坐标系在webgl中可以暂且将其当成右手坐标系, 下图就是右手坐标系 以上图为例 当物体绕 z 轴从x轴正半轴向y轴正半轴逆时针旋转时是正向旋转反之为负。当物体绕 x 轴从y轴正半轴向z轴正半轴逆时针旋转时是正向旋转反之为负。当物体绕 y 轴从z轴正半轴向x轴正半轴逆时针旋转时是正向旋转反之为负。 如下图就是正向旋转 围绕z轴(骑着z轴)从x轴到y轴逆时针转动就是正向旋转 旋转公式
如下让顶点围绕 z 轴旋转的场景 已知 点A的位置是(ax,ay,az)点A要围绕z轴旋转β度转到点B的位置 求点A旋转后的bx、by位置解 因为∠β是已知的∠α 可以通过点 A 得出所以我们可以得出∠xOB α β那我们通过三角函数就可以推出bx、by设 ∠xOB θ则bx cosθ * |OA|
by sinθ * |OA| // 注意这里因为是旋转, 所以 |OA| |OB|, 统一用 |OA|来表示上面的|OA|是点O到点A的距离可以直接用点A求出|OA| Math.sqrt(ax * ax ay * ay)那我们接下来只需要知道cosθ和sinθ的值即可因为θ α β所以我们可以利用和角公式求cosθ和sinθ的值cosθ cos(α β)
cosθ cosα * cosβ - sinα * sinβsinθ sin(α β)
sinθ cosβ * sinα sinβ * cosα所以bx cosθ * |OA|
bx (cosα * cosβ - sinα * sinβ) * |OA|
bx cosα * cosβ * |OA| - sinα * sinβ * |OA|by sinθ * |OA|
by (cosβ * sinα sinβ * cosα) * |OA|
by cosβ * sinα * |OA| sinβ * cosα * |OA|因为cosα * |OA| ax
sinα * |OA| ay所以我们可以简化bx、by的公式bx ax * cosβ - ay * sinβ
by ay * cosβ ax * sinβ上面的bx、by就是我们要求的答案
在着色器中旋转 可以直接在着色器里写旋转公式 script idvertexShader typex-shader/x-vertexattribute vec4 a_Position;float angle radians(80.0);float sinB sin(angle);float cosB cos(angle);void main() {gl_Position.x a_Position.x * cosB - a_Position.y * sinB;gl_Position.y a_Position.y * cosB a_Position.x * sinB;gl_Position.z a_Position.z;gl_Position.w 1.0;}
/scriptradians(float degree) 将角度转弧度 sin(float angle) 正弦 cos(float angle) 余弦
用js旋转图形
我们将顶点着色器里的正弦值和余弦值暴露给js便可以用js旋转图形了
script idvertexShader typex-shader/x-vertexattribute vec4 a_Position;uniform float u_SinB;uniform float u_CosB;void main() {gl_Position.x a_Position.x * u_CosB-a_Position.y * u_SinB;gl_Position.y a_Position.y * u_CosBa_Position.x * u_SinB;gl_Position.z a_Position.z;gl_Position.w 1.0;}
/script在js 中修改uniform 变量 const u_SinB gl.getUniformLocation(gl.program, u_SinB);
const u_CosB gl.getUniformLocation(gl.program, u_CosB);
const angle 0.3;
gl.uniform1f(u_SinB, Math.sin(angle));
gl.uniform1f(u_CosB, Math.cos(angle));之后让图形转起来 !(function ani() {angle 0.01;gl.uniform1f(u_SinB, Math.sin(angle));gl.uniform1f(u_CosB, Math.cos(angle));gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(ani);
})()完整代码
canvas idcanvas/canvas
script idvertexShader typex-shader/x-vertexattribute vec4 a_Position;uniform float u_SinB;uniform float u_CosB;void main() {gl_Position.x a_Position.x * u_CosB - a_Position.y * u_SinB;gl_Position.y a_Position.y * u_CosB a_Position.x * u_SinB;gl_Position.z a_Position.z;gl_Position.w 1.0;}
/script
script idfragmentShader typex-shader/x-fragmentvoid main() {gl_FragColor vec4(1.0,1.0,0.0,1.0);}
/script
script typemoduleimport { initShaders } from ./utils.js;const canvas document.getElementById(canvas);canvas.width window.innerWidth;canvas.height window.innerHeight;const gl canvas.getContext(webgl);const vsSource document.getElementById(vertexShader).innerText;const fsSource document.getElementById(fragmentShader).innerText;initShaders(gl, vsSource, fsSource);const vertices new Float32Array([0.0, 0.1,-0.1, -0.1,0.1, -0.1]);const vertexBuffer gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);const a_Position gl.getAttribLocation(gl.program, a_Position);gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);gl.enableVertexAttribArray(a_Position);// 获取Uniform变量const u_SinB gl.getUniformLocation(gl.program, u_SinB)const u_CosB gl.getUniformLocation(gl.program, u_CosB)// 修改uniform 变量let angle 0.3gl.uniform1f(u_SinB, Math.sin(angle))gl.uniform1f(u_CosB, Math.cos(angle))gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);!(function ani() {angle 0.01;gl.uniform1f(u_SinB, Math.sin(angle));gl.uniform1f(u_CosB, Math.cos(angle));gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, 3);requestAnimationFrame(ani);})()
/script