WebGL 绘制与变换使用示例详解

 更新时间:2023年04月19日 14:38:37   作者:H_World  
这篇文章主要为大家介绍了WebGL 绘制与变换使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

缓冲区对象(buffer object)

其中的API方法的说明官方网址:WebGLRenderingContext

紧接上一篇的问题,其实通过片元着色器可以修改点的颜色,但是会发现每一次颜色的都是一样的,两种方式的区别就是第一种用到了缓冲区对象

解释:buffer object,它可以一次性向着色器中传入多个顶点数据,而缓冲区对象是WebGL中一块内存区域,我们可以一次性向其中传入大量的顶点数据。

再来看一眼相关代码

api说明

  • createBuffer: creates and initializes a WebGLBuffer storing data such as vertices or colors -- 创建和初始化一个可以存储类似顶点和颜色数据的对象
  • bindBuffer: binds a given WebGLBuffer to a target -- 将buffer对象绑定到目标对象上
  • bufferData: initializes and creates the buffer object's data store -- 存储数据到创建的buffer对象中
  • enableVertexAttribArray: turns on the generic vertex attribute array at the specified index into the list of attribute arrays. -- 传入的参数是一个vertex类型的数组对象,这个方法可以依次打开这个数组
  • vertexAttribPointer: binds the buffer currently bound to gl.ARRAY_BUFFER to a generic vertex attribute of the current vertex buffer object and specifies its layout. -- 将整个数组中的所有值一次性分配给一个attribute变量

解析:首先创建多个长度的数组,用来装着色器中需要修改的顶点或是颜色信息,之后创建一个buffer,再将webgl对象和当前创建的buffer地址绑定一起,bufferData方法就是往buffer地址中传入数组数据

绘制图形

上面的例子中都是绘制一个点,只不过这个点的size可以自定义设置

webgl.drawArrays(webgl.POINTS, 0, points.length / 4)

其中的drawArrays中的第一个参数指的是不同的绘制方式

参数类型

  • gl.POINTS 点,绘制在坐标系内
  • gl.LINES 线,分别是点1和点2的线,点3和点4的线...
  • gl.LINE_STRIP 线,连接点1-点2-点3...
  • gl.LINE_LOOP 线,连接点1-点2-点3-点1,点的首尾相连
  • gl.TRIANGLES 三角形, 绘制在(点1,点2,点3)...
  • gl.TRIANGLE_STRIP 三角带,第二个三角形和第一个三角形共享一条边
  • gl.gl.TRIANGLE_FAN 三角扇

移动、旋转、缩放

const VSHADER_SOURCE = `
  attribute vec4 a_Position;
  uniform vec4 u_Translate;
  void main() {
     gl_Position = u_Translate + a_Position;
  }
 `
const u_Translate = gl.getUniformLocation(gl.program, 'u_Translate')
gl.uniform4f(u_Translate, 0.5, 0.5, 0.0, 0)

创建初始的坐标点

const u_Translate = gl.getUniformLocation(program, 'u_Translate');
// 定义顶点数据 
const positions = [ 0, 0, 0.5, 0, 0.5, 0.5, 0, 0.5, ];
// 将顶点数据写入缓冲区 
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// 启用属性并指定数据格式 
gl.enableVertexAttribArray(aPosition); 
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
// 设置平移向量 
const translation = [0.5, 0.5]; // 将平移向量传递给uniform变量 
gl.uniform2fv(translationUniformLocation, translation); // 绘制图形 
gl.drawArrays(gl.TRIANGLE_FAN, 0, positions.length / 2);

u_Translate + a_Position为每一个分量相加得到一个新的vec4值。

自动旋转

定义顶点着色器:一个顶点的信息,然后可以设置旋转中心点的锚点,旋转的角度,和一个需要改变的颜色

const vertexShaderSource = `
  attribute vec2 a_position;
  uniform vec2 u_rotationCenter;
  uniform float u_angle;
  varying vec3 v_color;
  void main() {
    vec2 rotatedPosition = vec2(
      cos(u_angle) * (a_position.x - u_rotationCenter.x) - sin(u_angle) * (a_position.y - u_rotationCenter.y) + u_rotationCenter.x,
      sin(u_angle) * (a_position.x - u_rotationCenter.x) + cos(u_angle) * (a_position.y - u_rotationCenter.y) + u_rotationCenter.y
    );
    gl_Position = vec4(rotatedPosition, 0, 1);
    v_color = vec3(cos(u_angle), 3.14 - cos(u_angle), cos(u_angle));
}
`

这样在片元着色器中就需要

const fragmentShaderSource = `
  precision mediump float;
  varying vec3 v_color;
  void main() {
    gl_FragColor = vec4(v_color, 1);
  }
`

v_color属性是从顶点着色器中绑定而来的

// 设置旋转中心和旋转角度
const rotationCenter = [0.25, 0.25];
let angle = 0
function render() {
  // 更新旋转角度
  angle += 0.01
  if (angle === 3.1415926) {
    angle = 0
  }
  // 将旋转中心和旋转角度传递给uniform变量
  webgl.uniform2fv(rotationCenterUniformLocation, rotationCenter)
  webgl.uniform1f(angleUniformLocation, angle)
  draw()
  // 绘制图形
  webgl.drawArrays(webgl.TRIANGLE_FAN, 0, 4);
  // 请求浏览器调用下一帧动画
  requestAnimationFrame(render)
}
// 开始动画
render()

缩放

demo实现:根据滑动鼠标控制三角形中的缩放大小

代码实现

var vertexShaderSource = `
  attribute vec3 aVertexPosition;
  uniform float uScale;
  void main() {
    gl_Position = vec4(aVertexPosition * uScale, 1.0);
  }
`

顶点着色器中定义了uniform的变量uScale,比例因子,通过之后的代码中

const scaleUniformLocation = webgl.getUniformLocation(webgl.program, "uScale")
webgl.uniform1f(scaleUniformLocation, scale)

重新设置该变量的值 监听鼠标滑动事件

canvas.addEventListener("wheel", function (event: any) {
  scale += event.deltaY / 1000
})

补充说明

变换中主要用到是矩阵的知识,矩阵按储存方式分为按行矩阵和按列矩阵,而WebGL中主要是按列矩阵

那么使用矩阵可以 <新坐标> = <变换矩阵> * <旧坐标>

以上就是WebGL 绘制与变换使用示例详解的详细内容,更多关于WebGL绘制变换的资料请关注脚本之家其它相关文章!

相关文章

  • 鼠标经过tr时,改变tr当前背景颜色

    鼠标经过tr时,改变tr当前背景颜色

    本篇文章主要介绍了鼠标经过tr时,改变tr当前背景颜色的示例代码,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • JavaScript实现导入导出excel的示例代码

    JavaScript实现导入导出excel的示例代码

    这篇文章主要为大家详细介绍了如何利用JavaScript语言实现导入导出excel文件的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-07-07
  • 微信小程序判断手机号是否合法的实例代码

    微信小程序判断手机号是否合法的实例代码

    我们在微信小程序开发的时候,手机号的验证是经常需要操作的,那么如何验证手机号呢?这篇文章主要给大家介绍了关于微信小程序判断手机号是否合法的相关资料,需要的朋友可以参考下
    2021-09-09
  • js分页显示div的内容

    js分页显示div的内容

    对于div内容过高的情况,我们可以用js控制div分页
    2008-07-07
  • JS实现表单全选以及取消全选实例

    JS实现表单全选以及取消全选实例

    这篇文章主要为大家详细介绍了JS实现表单全选以及取消全选实例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Three.js利用orbit controls插件(轨道控制)控制模型交互动作详解

    Three.js利用orbit controls插件(轨道控制)控制模型交互动作详解

    这篇文章主要给大家介绍了关于Three.js利用orbit controls插件,也就是轨道控制来控制模型交互动作的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-09-09
  • JavaScript中String对象的方法介绍

    JavaScript中String对象的方法介绍

    本文主要对JavaScript中String对象的方法进行介绍。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • JavaScript Array对象详解

    JavaScript Array对象详解

    这篇文章主要为大家详细介绍了JavaScript function函数种类,知识点很全面,包括普通函数、匿名函数、闭包函数,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 简单了解JavaScript中常见的反模式

    简单了解JavaScript中常见的反模式

    这篇文章主要介绍了简单了解JavaScript中常见的反模式,反模式 是指对反复出现的设计问题的常见的无力而低效的设计模式,俗话说就是重蹈覆辙。 这篇文章描述了 JavaScript 中常见的一些反模式,以及避免它们的办法。,需要的朋友可以参考下
    2019-06-06
  • JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码

    JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码

    最近看到朋友用JavaScript实现仿新浪微博大厅和未登录腾讯微博首页滚动效果,朋友使用jquery实现的,在网上看到有用js制作的也比较好,于是把我的内容整理分享给大家,具体详解请看本文
    2015-09-09

最新评论