码迷,mamicode.com
首页 > Web开发 > 详细

WebGL(6) -- 仿射变换

时间:2016-02-05 22:11:02      阅读:545      评论:0      收藏:0      [点我收藏+]

标签:

本文参考《WebGL编程指南》

 

  仿射变换:移动,旋转,缩放

  在做变换时,通常是使用矩阵。

 

首先画出一个初始的三角形作为对比:

技术分享

源码:

test.js

技术分享
function main() {
  var gl = Init();
  if(!gl) {
    console.log(‘Failed to init‘);
    return;
  }

  var n = InitVertices(gl);
  if(n < 0) {
    console.log(‘Failed to init vertices‘);
    return;
  }

  // draw triangle
  gl.drawArrays(gl.TRIANGLES, 0, n);
  // draw coordinate system
  gl.drawArrays(gl.LINES, n, 4);

}

//@Func: init the WebGL
//@Return: gl(the WebGL context)
function Init() {
  var canvas = document.getElementById(‘webgl‘);

  var gl = getWebGLContext(canvas);
  if(!gl) {
    console.log(‘Failed to get the rendering context for WebGL‘);
    return null;
  }

  if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log(‘Failed to init shader‘);
    return null;
  }

  gl.clearColor(0.3, 1.0, 0.3, 1.0);

  gl.clear(gl.COLOR_BUFFER_BIT);

  return gl;
}

//@Func: init vertices
//@Return: n(the number of vertex)
function InitVertices(gl) {
  var vertexBuffer = gl.createBuffer();
  if(!vertexBuffer) {
    console.log(‘Failed to create vertex buffer‘);
    return -1;
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

  var n = 3;
  var vertices = new Float32Array([
      -0.3,0.0, 0.0,0.5, 0.3,0.0,
      -1.0,0.0, 1.0,0.0, 0.0,-1.0,
      0.0,1.0
    ]);

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(gl.program, ‘aPos‘);
  if(aPos < 0) {
    console.log(‘Failed to get aPos‘);
    return -1;
  }

  gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPos);

  return n;
}
View Code

shader.js

技术分享
// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  void main() {
    gl_Position = aPos; 
    gl_PointSize = 30.0;
  }
`

// fragment shader
var FSHADER_SOURCE = 
`
  precision mediump float;
  //uniform vec4 uColor;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`
View Code

 

  移动

平移矩阵如下:

技术分享

(1)在着色器中做矩阵运算

// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  uniform mat4 uTransform;
  void main() {
    gl_Position = uTransform * aPos; 
    gl_PointSize = 30.0;
  }
`

 

(2)赋值给矩阵

var transformMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.3, 0.0, 0.0, 1.0
    ]);

  var uTransform = gl.getUniformLocation(gl.program, ‘uTransform‘);

  gl.uniformMatrix4fv(uTransform, false, transformMatrix);

 

注意:矩阵是列主元的,即上面定义的矩阵实际是如下:

技术分享

效果:

技术分享

源码:

test.js

技术分享
function main() {
  var gl = Init();
  if(!gl) {
    console.log(‘Failed to init‘);
    return;
  }

  var n = InitVertices(gl);
  if(n < 0) {
    console.log(‘Failed to init vertices‘);
    return;
  }

  var transformMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.3, 0.0, 0.0, 1.0
    ]);

  var uAffineMat = gl.getUniformLocation(gl.program, ‘uAffineMat‘);

  gl.uniformMatrix4fv(uAffineMat, false, transformMatrix);

  // draw triangle
  gl.drawArrays(gl.TRIANGLES, 0, n);

  var normalMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  gl.uniformMatrix4fv(uAffineMat, false, normalMatrix);

  // draw coordinate system
  gl.drawArrays(gl.LINES, n, 4);

}

//@Func: init the WebGL
//@Return: gl(the WebGL context)
function Init() {
  var canvas = document.getElementById(‘webgl‘);

  var gl = getWebGLContext(canvas);
  if(!gl) {
    console.log(‘Failed to get the rendering context for WebGL‘);
    return null;
  }

  if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log(‘Failed to init shader‘);
    return null;
  }

  gl.clearColor(0.3, 1.0, 0.3, 1.0);

  gl.clear(gl.COLOR_BUFFER_BIT);

  return gl;
}

//@Func: init vertices
//@Return: n(the number of vertex)
function InitVertices(gl) {
  var vertexBuffer = gl.createBuffer();
  if(!vertexBuffer) {
    console.log(‘Failed to create vertex buffer‘);
    return -1;
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

  var n = 3;
  var vertices = new Float32Array([
      -0.3,0.0, 0.0,0.5, 0.3,0.0,
      -1.0,0.0, 1.0,0.0, 0.0,-1.0,
      0.0,1.0
    ]);

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(gl.program, ‘aPos‘);
  if(aPos < 0) {
    console.log(‘Failed to get aPos‘);
    return -1;
  }

  gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPos);

  return n;
}
View Code

 

shader.js

技术分享
// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  uniform mat4 uAffineMat;
  void main() {
    gl_Position = uAffineMat * aPos; 
    gl_PointSize = 30.0;
  }
`

// fragment shader
var FSHADER_SOURCE = 
`
  precision mediump float;
  //uniform vec4 uColor;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`
View Code

 

 

   旋转

旋转矩阵如下:

技术分享

效果:

技术分享

源码:

test.js

技术分享
function main() {
  var gl = Init();
  if(!gl) {
    console.log(‘Failed to init‘);
    return;
  }

  var n = InitVertices(gl);
  if(n < 0) {
    console.log(‘Failed to init vertices‘);
    return;
  }

  var angle = 3.14 / 4;

  var transformMatrix = new Float32Array([
    Math.cos(angle), Math.sin(angle), 0.0, 0.0,
    -Math.sin(angle), Math.cos(angle), 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  var uAffineMat = gl.getUniformLocation(gl.program, ‘uAffineMat‘);

  gl.uniformMatrix4fv(uAffineMat, false, transformMatrix);

  // draw triangle
  gl.drawArrays(gl.TRIANGLES, 0, n);

  var normalMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  gl.uniformMatrix4fv(uAffineMat, false, normalMatrix);

  // draw coordinate system
  gl.drawArrays(gl.LINES, n, 4);

}

//@Func: init the WebGL
//@Return: gl(the WebGL context)
function Init() {
  var canvas = document.getElementById(‘webgl‘);

  var gl = getWebGLContext(canvas);
  if(!gl) {
    console.log(‘Failed to get the rendering context for WebGL‘);
    return null;
  }

  if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log(‘Failed to init shader‘);
    return null;
  }

  gl.clearColor(0.3, 1.0, 0.3, 1.0);

  gl.clear(gl.COLOR_BUFFER_BIT);

  return gl;
}

//@Func: init vertices
//@Return: n(the number of vertex)
function InitVertices(gl) {
  var vertexBuffer = gl.createBuffer();
  if(!vertexBuffer) {
    console.log(‘Failed to create vertex buffer‘);
    return -1;
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

  var n = 3;
  var vertices = new Float32Array([
      -0.3,0.0, 0.0,0.5, 0.3,0.0,
      -1.0,0.0, 1.0,0.0, 0.0,-1.0,
      0.0,1.0
    ]);

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(gl.program, ‘aPos‘);
  if(aPos < 0) {
    console.log(‘Failed to get aPos‘);
    return -1;
  }

  gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPos);

  return n;
}
View Code

shader.js

技术分享
// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  uniform mat4 uAffineMat;
  void main() {
    gl_Position = uAffineMat * aPos; 
    gl_PointSize = 30.0;
  }
`

// fragment shader
var FSHADER_SOURCE = 
`
  precision mediump float;
  //uniform vec4 uColor;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`
View Code

 

  缩放

缩放矩阵如下:

技术分享

效果:

技术分享

源码:

test.js

技术分享
function main() {
  var gl = Init();
  if(!gl) {
    console.log(‘Failed to init‘);
    return;
  }

  var n = InitVertices(gl);
  if(n < 0) {
    console.log(‘Failed to init vertices‘);
    return;
  }

  var angle = 3.14 / 4;

  var transformMatrix = new Float32Array([
    2, 0, 0.0, 0.0,
    0, 0.5, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  var uAffineMat = gl.getUniformLocation(gl.program, ‘uAffineMat‘);

  gl.uniformMatrix4fv(uAffineMat, false, transformMatrix);

  // draw triangle
  gl.drawArrays(gl.TRIANGLES, 0, n);

  var normalMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  gl.uniformMatrix4fv(uAffineMat, false, normalMatrix);

  // draw coordinate system
  gl.drawArrays(gl.LINES, n, 4);

}

//@Func: init the WebGL
//@Return: gl(the WebGL context)
function Init() {
  var canvas = document.getElementById(‘webgl‘);

  var gl = getWebGLContext(canvas);
  if(!gl) {
    console.log(‘Failed to get the rendering context for WebGL‘);
    return null;
  }

  if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log(‘Failed to init shader‘);
    return null;
  }

  gl.clearColor(0.3, 1.0, 0.3, 1.0);

  gl.clear(gl.COLOR_BUFFER_BIT);

  return gl;
}

//@Func: init vertices
//@Return: n(the number of vertex)
function InitVertices(gl) {
  var vertexBuffer = gl.createBuffer();
  if(!vertexBuffer) {
    console.log(‘Failed to create vertex buffer‘);
    return -1;
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

  var n = 3;
  var vertices = new Float32Array([
      -0.3,0.0, 0.0,0.5, 0.3,0.0,
      -1.0,0.0, 1.0,0.0, 0.0,-1.0,
      0.0,1.0
    ]);

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(gl.program, ‘aPos‘);
  if(aPos < 0) {
    console.log(‘Failed to get aPos‘);
    return -1;
  }

  gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPos);

  return n;
}
View Code

 

shader.js

技术分享
// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  uniform mat4 uAffineMat;
  void main() {
    gl_Position = uAffineMat * aPos; 
    gl_PointSize = 30.0;
  }
`

// fragment shader
var FSHADER_SOURCE = 
`
  precision mediump float;
  //uniform vec4 uColor;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`
View Code

 

 

  多个变换组合在一起

要将多个仿射变换组合在一起,只需要将对应的变换矩阵相乘。

利用cuon-matrix.js,其中定义了有用的矩阵运算:

var affineMat = new Matrix4();
  affineMat.setTranslate(0.3, 0.0, 0.0);
  affineMat.scale(2, 0.5, 1);
  
  var uAffineMat = gl.getUniformLocation(gl.program, ‘uAffineMat‘);

  gl.uniformMatrix4fv(uAffineMat, false, affineMat.elements);

 

效果:

技术分享

源码:

test.js

技术分享
function main() {
  var gl = Init();
  if(!gl) {
    console.log(‘Failed to init‘);
    return;
  }

  var n = InitVertices(gl);
  if(n < 0) {
    console.log(‘Failed to init vertices‘);
    return;
  }

  var affineMat = new Matrix4();
  affineMat.setTranslate(0.3, 0.0, 0.0);
  affineMat.scale(2, 0.5, 1);
  
  var uAffineMat = gl.getUniformLocation(gl.program, ‘uAffineMat‘);

  gl.uniformMatrix4fv(uAffineMat, false, affineMat.elements);

  // draw triangle
  gl.drawArrays(gl.TRIANGLES, 0, n);

  var normalMatrix = new Float32Array([
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
    ]);

  gl.uniformMatrix4fv(uAffineMat, false, normalMatrix);

  // draw coordinate system
  gl.drawArrays(gl.LINES, n, 4);

}

//@Func: init the WebGL
//@Return: gl(the WebGL context)
function Init() {
  var canvas = document.getElementById(‘webgl‘);

  var gl = getWebGLContext(canvas);
  if(!gl) {
    console.log(‘Failed to get the rendering context for WebGL‘);
    return null;
  }

  if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log(‘Failed to init shader‘);
    return null;
  }

  gl.clearColor(0.3, 1.0, 0.3, 1.0);

  gl.clear(gl.COLOR_BUFFER_BIT);

  return gl;
}

//@Func: init vertices
//@Return: n(the number of vertex)
function InitVertices(gl) {
  var vertexBuffer = gl.createBuffer();
  if(!vertexBuffer) {
    console.log(‘Failed to create vertex buffer‘);
    return -1;
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

  var n = 3;
  var vertices = new Float32Array([
      -0.3,0.0, 0.0,0.5, 0.3,0.0,
      -1.0,0.0, 1.0,0.0, 0.0,-1.0,
      0.0,1.0
    ]);

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

  var aPos = gl.getAttribLocation(gl.program, ‘aPos‘);
  if(aPos < 0) {
    console.log(‘Failed to get aPos‘);
    return -1;
  }

  gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPos);

  return n;
}
View Code

 

shader.js

技术分享
// vertical shader
var VSHADER_SOURCE = 
`
  attribute vec4 aPos;
  uniform mat4 uAffineMat;
  void main() {
    gl_Position = uAffineMat * aPos; 
    gl_PointSize = 30.0;
  }
`

// fragment shader
var FSHADER_SOURCE = 
`
  precision mediump float;
  //uniform vec4 uColor;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`
View Code

 

WebGL(6) -- 仿射变换

标签:

原文地址:http://www.cnblogs.com/programmer-kaima/p/5182074.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!