【笔记】《WebGL编程指南》学习-第2章WebGL入门(4-画一个点-版本2))

在上一节的JS文件里,我们将点的位置是直接编写在顶点着色器中的,虽然易于理解,但缺乏可扩展性。所以这一节,我们要将顶点的位置坐标从JS传到着色器程序中,然后再对应位置上将点绘制出来。虽然结果一样,但用到的方法是可扩展的。


目标:用另一种更灵活地方法绘制一个最简单的图形-点(位于原点(0.0,0.0,0.0)处,大小10像素)!
结果:


使用attribute变量

我们要将位置信息从JS程序中传给顶点着色器,有两种方式可以做到这点:

  • attribute变量
  • uniform变量

使用哪一个变量取决于需要传输的数据本身,attribute 变量传输的是那些与顶点相关的数据,而 unuform 变量传输的是那些对于所有顶点都想通的数据。本例使用 attribute 变量来传输顶点坐标。

为了使用 attribute 变量,需要包含以下步骤:

  1. 在顶点着色器中,声明 attribute 变量;
  2. 将 attribute 变量赋值给 gl_Position 变量;
  3. 向 attribute 变量传输数据。

HelloPoint2.js

HelloPoint2.js

//顶点着色器程序
var VSHADER_SOURCE =
    'attribute vec4 a_Position;'+
    'void main(){'+
        'gl_Position=a_Position;'+
        'gl_PointSize=10.0;'+
    '}';

//片元着色器程序
var FSHADER_SOURCE=
    'void main(){'+
    'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);'+
    '}';

function main() {
    //获取canvas元素
    var canvas = document.getElementById("webgl");
    if(!canvas){
        console.log("Failed to retrieve the <canvas> element");
        return;
    }

    //获取WebGL绘图上下文
    var gl = getWebGLContext(canvas);
    if(!gl){
        console.log("Failed to get the rendering context for WebGL");
        return;
    }

    //初始化着色器
    if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
        console.log("Failed to initialize shaders.");
        return;
    }

    //获取attribute变量存储位置
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

    if(a_Position < 0){
        console.log("Failed to get the storage location of a_Position");
        return;
    }

    //将顶点位置传输给attribute变量
    gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.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);
}

我们在着色器中声明了 attribute 变量:

'attribute vec4 a_Position;'+

这一行中,关键词 attribute 被称为存储限定符(storage qualifier),它表示接下来的变量是一个 attribute 变量。attribute 变量必须声明成全局变量,数据将从着色器外部传给该变量。

一旦声明 a_Position 之后,我们将其赋值给 gl_Position:

'gl_Position=a_Position;'+

获取 attribute 变量的存储位置

每个变量都具有一个存储地址,以便通过存储地址向变量传输数据。

//获取attribute变量存储位置
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

方法的第一个参数是程序对象,它包括了顶点着色器和片元着色器。第二个参数是想要获取存储地址的 attribute 变量的名称。

方法的返回值是 attribute 变量的存储地址。这个地址存储在JS变量 a_Position中,之后使用。


向 attribute 变量赋值

我们使用 gl.vertexAttrib3f()向着色器传入值

    //将顶点位置传输给attribute变量
    gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);

该函数的第1个参数是 attribute 变量的存储地址,第2,3,4个参数是三个浮点型数值,即点的x, y和z坐标值。函数被调用后,这三个值被一起传给顶点坐标其中的 a_Position变量。

接着,在顶点着色器中,a_Position 的值就被赋给了 gl_Position,这样我们就成功将点的x、y和z的坐标值从JS传入了着色器,并赋值给了gl_Position。

你可能已经注意到,在顶点着色器的变量声明里,a_Postion 变量是 vec4 类型的,但是gl.vertexAttrib3f()仅传了三个分量值(x、y、z)而不是4个。其实是如果你省略了第4个参数,这个方法就会默认地将第4个分量设置为了1.0。

gl.vertexAttrib3f()同族函数

gl.vertexAttrib3f()是一系列同族函数中的一个,该系列函数的任务就是从JS向顶点着色器中的 attribute 变量传值。
这里写图片描述


结果

其实和昨天的是一样的,只是实现这一结果的的第二种方法
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值