缩放
1 )原理
- 缩放可以理解为对向量长度的改变,或者对向量坐标分量的同步缩放 
  
- 如下图,比如
 - 让向量OA 收缩到点B的位置,也就是从OA变成OB,缩放了一半
 
 
 
 2 )公式
-  
已知
- 点A的位置是(ax,ay,az)
 - 点A基于原点內缩了一半
 
 -  
求
- 点A內缩了一半后的bx、by、bz位置B
 
 -  
解
bx = ax * 0.5 by = ay * 0.5 bz = az * 0.5 
在着色器中缩放
1 )核心代码
-  
可以对gl_Position 的x、y、z依次缩放
<script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; float scale = 1.2; // 注意这里声明了浮点型,一点要用浮点数,否则会导致 UseProgram: program not valid 的警告 void main() { gl_Position.x = a_Position.x * scale; gl_Position.y = a_Position.y * scale; gl_Position.z = a_Position.z * scale; gl_Position.w = 1.0; // 注意 w 的值,默认1.0 } </script> -  
也可以从a_Position中抽离出由x、y、z组成的三维向量,对其进行一次性缩放
<script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; float scale = 1.2; void main() { gl_Position = vec4(vec3(a_Position) * scale, 1.0); } </script> 
2 )完整代码
<canvas id="canvas"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
  attribute vec4 a_Position;
  float scale = 1.0;
  void main() {
      gl_Position = vec4(vec3(a_Position) * scale, 1.0);
  }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
  void main(){
      gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
  }
</script>
<script type="module">
  import { 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);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
 
用js缩放图形
1 )核心代码
- 同样的我们也可以把缩放系数暴露给js,通过js 缩放图形 
  
- 建立uniform变量
<script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; uniform float u_Scale; void main() { gl_Position = vec4(vec3(a_Position) * u_Scale, 1.0); } </script> - 使用js获取并修改uniform 变量
const u_Scale = gl.getUniformLocation(gl.program, 'u_Scale') gl.uniform1f(u_Scale, 1.0) - 添加动画让其动起来
let angle = 0 !(function animate() { angle += 0.05; const scale = Math.sin(n) + 1; // 借助三角函数正弦进行缩放 (-1, 1) + 1 => (0, 2) gl.uniform1f(u_Scale, scale); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 3); requestAnimationFrame(animate) })() 
 - 建立uniform变量
 
2 )完整代码
<canvas id="canvas"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
  attribute vec4 a_Position;
  uniform float u_Scale;
  void main() {
      gl_Position = vec4(vec3(a_Position) * u_Scale, 1.0);
  }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
  void main() {
      gl_FragColor = vec4(1.0,1.0,0.0,1.0);
  }
</script>
<script type="module">
  import { 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);
  const u_Scale = gl.getUniformLocation(gl.program, 'u_Scale')
  gl.uniform1f(u_Scale, 1);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
  let angle = 0;
  !(function animate() {
    angle += 0.05;
    const scale = Math.sin(angle) + 1;
    gl.uniform1f(u_Scale, scale);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, 3);
    requestAnimationFrame(animate);
  })()
</script>
                


















