WebGL入门(三)-在JavaScript程序通过attribute变量向顶点着色器传值

1.demo效果

在这里插入图片描述
如上图,这个demo和上一个效果一样,但是实现时却不同,这一次在JavaScript程序中通过 gl.getAttribLocation() 方法获取着色器中的变量a_Position的地址,然后通过 gl.vertexAttrib3f() 方法向着色器变量a_Position传值,最后将图形呈现在页面中。

2.相关知识点

2.1 着色器中的attribute变量

attribute变量是一种GLSL ES变量,被用来从外部向顶点着色器传输数据。接下来介绍一下attribute变量的声明,该变量的声明有一定的格式要求:<存储限定符><类型><变量名>
在这里插入图片描述
友情提示:

  1. attribute变量必须声明成全局变量
  2. 所有的attribute变量最好以a_前缀开始,这样从变量的名字就可以区分出类型

2.2 gl.getAttribLocation()方法

我们在着色器程序中声明的attribute变量都会有一个自己的存储地址,通过这个地址我们可以在外部程序中给它赋值,gl.getAttribLocation() 方法就是帮我们获取这个地址的利器

函数功能:获取有name指定的着色器中attribute变量的存储地址
--------------------------------------------------------------------------
调用示例:gl.getAttribLocation(program, name)
--------------------------------------------------------------------------
参数		
			program				指定包含顶点着色器和片元着色器的着色器程序对象  
			name				指定想要获取其存储地址的attribute变量名称
--------------------------------------------------------------------------			
返回值		>=0					attribute变量的存储地址
			-1					指定的变量名不存在,或命名具有gl_或webgl_前缀
--------------------------------------------------------------------------
错  误		INVALID_OPERATION	程序对象未能连接成功
			INVALID_VALUE		name参数的长度大于最大长度,默认256字节		

示例代码

//获取着色器attribute变量a_Position的存储地址
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

2.3 gl.vertexAttrib3f()方法

gl.getAttribLocation() 方法帮我们获取到了着色器变量的地址,这时就需要请出gl.vertexAttrib3f() 方法了,通过这个方法我们就可以在JavaScript程序中把想要赋的值赋给着色器中的attribute变量

函数功能:将数据v0, v1, v2 传给由location参数指定的着色器的attribute变量
------------------------------------------------------------------------------
调用示例:gl.vertexAttrib3f(location, v0, v1, v2)
------------------------------------------------------------------------------
参数		
			location			指定将要修改的attribute变量的存储地址  
			v0					指定填充attribute变量第一个分量的值
			v1					指定填充attribute变量第二个分量的值
			v2					指定填充attribute变量第三个分量的值
------------------------------------------------------------------------------			
返回值		无
------------------------------------------------------------------------------
错  误		INVALID_OPERATION	没有当前的program对象
			INVALID_VALUE		location大于等于attribute变量的最大数据,默认为8		

示例代码

//向着色器attribute变量a_Position传值
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)

2.4 gl.vertexAttrib3f()的同族函数

gl.vertexAttrib3f() 方法是一系列同族函数中的一个,该系列函数的任务就是从JavaScript程序中向顶点着色器中的attribute变量传值

函数功能:将数据[1~4个分量]传给由location参数指定的着色器的attribute变量
------------------------------------------------------------------------------
gl.vertexAttrib1f(location, v0)
gl.vertexAttrib2f(location, v0, v1)
gl.vertexAttrib3f(location, v0, v1, v2)
gl.vertexAttrib4f(location, v0, v1, v2, v3)
------------------------------------------------------------------------------
参数		
			location			指定将要修改的attribute变量的存储地址  
			v0,v1,v2,v3			指定传输给attribute变量的四个分量的值
------------------------------------------------------------------------------			
返回值		无
------------------------------------------------------------------------------
错  误		INVALID_VALUE		location大于等于attribute变量的最大数据,默认为8		

你同样可以使用这些方法的矢量版本,它们的名字以"v"作为结尾。并接受类型化数组作为参数,函数名中数字表示数组中元素的个数

var position = new Float32Array([1.0,2.0,3.0,1.0]);
gl.vertexAttrib4fv(position);

2.5 attribute变量使用流程介绍

attribute变量的使用大致流程为:

  1. 在着色器中声明attribute变量
  2. 在JavaScript程序中获取attribute变量的存储地址
  3. 通过attribute变量的存储地址向着色器中的attribute变量传值

为了帮大家更直观的理解,我画了一张图,如有不足,请多多指正
在这里插入图片描述

3.demo代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <!--通过canvas标签创建一个400px*400px大小的画布-->
  <canvas id="webgl" width="400" height="400"></canvas>

  <script>
    //通过getElementById()方法获取canvas画布
    var canvas = document.getElementById('webgl');
    //通过方法getContext()获取WebGL上下文
    var gl = canvas.getContext('webgl');

    //顶点着色器
    var VSHADER_SOURCE = '' +
      'attribute vec4 a_Position;\\n' + //声明attribute变量a_Position,用来存放顶点位置信息
      'attribute float a_PointSize;\\n' + //声明attribute变量a_PointSize,用来存放顶点大小信息
      'void main(){\\n' +
      '  gl_Position = a_Position;\\n' + //变量a_Position赋值给顶点着色器内置变量gl_Position
      '  gl_PointSize = a_PointSize;\\n' + //变量a_PointSize赋值给顶点着色器内置变量gl_PointSize
      '}\\n';

    //片元着色器
    var FSHADER_SOURCE = '' +
      'void main(){\\n' +
      //设置片元颜色(红色)
      ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);\\n' +
      '}\\n';

    //初始化着色器
    initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE);

    //获取着色器attribute变量a_Position的存储地址
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    //向着色器attribute变量a_Position传值
    gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)

    //获取着色器attribute变量a_PointSize的存储地址
    var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
    //向着色器attribute变量a_PointSize传值
    gl.vertexAttrib1f(a_PointSize, 30.0)


    // 设置canvas的背景色
    gl.clearColor(0.0, 0.0, 0.0, 1.0);

    //清空canvas
    gl.clear(gl.COLOR_BUFFER_BIT);

    //开始绘制,绘制顶点,从第一个顶点开始绘制,绘制一个顶点
    gl.drawArrays(gl.POINTS, 0, 1);

    //初始化着色器函数
    function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE) {
      //创建顶点着色器对象
      var vertexShader = gl.createShader(gl.VERTEX_SHADER);
      //创建片元着色器对象
      var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      //引入顶点、片元着色器源代码
      gl.shaderSource(vertexShader, VSHADER_SOURCE);
      gl.shaderSource(fragmentShader, FSHADER_SOURCE);
      //编译顶点、片元着色器
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);

      //创建程序对象program
      var program = gl.createProgram();
      //附着顶点着色器和片元着色器到program
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      //链接program
      gl.linkProgram(program);
      //使用program
      gl.useProgram(program);
      gl.program = program
      //返回程序program对象
      return program;
    }
  </script>
</body>

</html>

© 版权声明
THE END
喜欢就支持一下吧
点赞771 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容