2.着色器(shader)

1.什么是着色器:着色器提供了灵活且强大的绘制二维和三维图形的方法,所有WebGL程序必须使用它。着色器处理完的结果存储在颜色缓冲区中。

2.几种着色器:

    顶点着色器(Vertex shader):用来描述顶点特性(如位置、颜色等)的程序。

                        顶点着色器对图像的顶点逐点进行处理,即要执行n次(n为顶点个数)

    片元着色器(Fragment shader):进行逐片元处理过程如光照的程序。

3.JavaScript与着色器程序的执行过程:

    首先着色器代码通过字符串的形式存储在JavaScript变量中(着色器代码必须含有main方法并且必须预处理成单个字符串的形式,用“+”进行连接),当JavaScript代码运行到初始化着色器时,着色器在WebGL系统(不是JavaScript程序)中开始运行,并根据着色器的定义对图形进行操作,然后将结果输出在颜色缓冲区中。

4.着色器代码中的变量在JavaScript中赋值(着色器代码都以字符串形式进行存储):

    存储限定符:attribute  和  uniform。attribute变量传输的是与顶点相关的数据,uniform变量存储的是对于所有顶点都相同(或与顶点无关)的数据。

    注意:getAttribLocation方法如果访问的变量地址不存在,返回-1;而getUniformLocation方法返回的是null

    声明格式:<存储限定符><类型><变量名>

attribute vec4 a_Position
uniform vec4 u_FragColor

  在着色器代码中使用存储限定符修饰声明变量,在JavaScript代码中可以通过预留方法请求到该变量在WebGL系统中的变量地址,并对该变量进行赋值。

    在JavaScript程序中获取着色器中的变量地址并对它进行赋值:

        gl.getAttribLoaction( program , name )

        program : 指定包含着色器的着色器程序对象

        name : 想要获取其存储地址的attribute变量的名称

    gl.vertexAttrib3f( location , v0 , v1 , v2)ver

        location : 要改变的变量的存储位置

        v0 : 指定填充attribute变量的第一个分量,其余分量设为默认值

        v1 : 指定填充attribute变量的第二个分量,其余分量设为默认值

        v2 : 指定填充attribute变量的第三个分量,其余分量设为默认值

    vertexAttrib3f的同族函数:

        首先WebGL相关函数明明规范是:<基础函数名><参数个数><参数类型>

        那么该方法的结构就是:vertexAttrib+n+参数类型+v(可不加),n代表参数个数,参数类型有 i (整数)、f (浮点数),v代表向量即可接受数组作为参数

5.顶点着色器和片元着色器之间的传值

    使用varying变量从顶点着色器传值到片元着色器:在WebGL中,顶点着色器与片元着色器中类型和命名相同的varying变量的值会自动由顶点着色器传入到片元着色器

var SHADER_SOURCE =
'attribute vec4 a_Position;\n'+
'attribute float a_PointSize;\n' +
'attribute vec4 a_Color;\n' +
'varying vec4 v_Color;\n'+
'void main(){\n'+
'gl_Position = a_Position;\n'+
'gl_PointSize = a_PointSize;\n' +
'v_Color = a_Color;\n'+
'}\n';

var FSHADER_SOURCE =
'precision mediump float;\n'+
'varying vec4 v_Color;\n'+
'void main(){\n'+
'gl_FragColor = v_Color;\n'+
'}\n';

function main()
{
var canvas = document.getElementById("webgl");
if(!canvas)
{
console.log("获取canvas标签失败");
}
var gl = canvas.getContext("webgl");
if(!gl)
{
console.log("获取上下文失败");
}
if(!initShaders(gl,SHADER_SOURCE,FSHADER_SOURCE))
{
console.log("加载着色器程序失败");
}

var n = initVertexBuffers(gl);
if(n<0)
{
console.log("设置顶点失败");
}

gl.drawArrays(gl.POINTS,0,n);

}

function initVertexBuffers(gl)
{
var vertices = new Float32Array([
0.0,0.5,10.0,1.0,0.0,0.0,
-0.5,-0.5,20.0,0.0,1.0,0.0,
0.5,-0.5,30.0,0.0,0.0,1.0,
]);
var n = 3; //顶点个数

//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer)
{
console.log("创建缓冲区失败");
return -1;
}
var FSIZE = vertices.BYTES_PER_ELEMENT;
//将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//向缓冲区对象写入数据
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program,'a_Position');
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,FSIZE*6,0);
//连接a_Position变量与分配给他的缓冲区对象
gl.enableVertexAttribArray(a_Position);

var sizeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,sizeBuffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
var a_PointSize = gl.getAttribLocation(gl.program,'a_PointSize');
gl.vertexAttribPointer(a_PointSize,1,gl.FLOAT,false,FSIZE*6,FSIZE*2);
gl.enableVertexAttribArray(a_PointSize);

var a_Color = gl.getAttribLocation(gl.program,'a_Color');
var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,FSIZE*6,FSIZE*3);
gl.enableVertexAttribArray(a_Color);

return n;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值