您的位置:首页 > 编程语言

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

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

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

结果:

使用attribute变量

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

attribute变量

uniform变量

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

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

在顶点着色器中,声明 attribute 变量;

将 attribute 变量赋值给 gl_Position 变量;

向 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 变量传值。



结果

其实和昨天的是一样的,只是实现这一结果的的第二种方法

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  webgl 图形
相关文章推荐