javascript基础学习系列二百九十九:GLSL 100 升级到 GLSL 300

本文介绍了WebGL2对GLSL3.00ES的升级,涉及新着色器功能、语法变化,如顶点属性和varying声明的调整,以及纹理处理的统一。同时详细讲解了WebGL的基本绘图方法和纹理应用,包括不同绘制模式和纹理创建过程。
摘要由CSDN通过智能技术生成

WebGL2 的主要变化是升级到了 GLSL 3.00 ES 着色器。这个升级暴露了很多新的着色器功能,包括 3D 纹理等在支持 OpenGL ES 3.0 的设备上都有的功能。要使用升级版的着色器,着色器代码的第一行必须是: 27
#version 300 es
这个升级需要一些语法的变化。
 顶点 attribute 变量要使用 in 而不是 attribute 关键字声明。
 使用 varying 关键字为顶点或片段着色器声明的变量,现在必须根据相应着色器的行为改为使 用in或out。
 预定义的输出变量 gl_FragColor 没有了,片段着色器必须为颜色输出声明自己的 out 变量。
 纹理查找函数 texture2D 和 textureCube 统一成了一个 texture 函数。

绘图

WebGL 只能绘制三种形状:点、线和三角形。其他形状必须通过这三种基本形状在 3D 空间的组合 来绘制。WebGL 绘图要使用 drawArrays()和 drawElements()方法,前者使用数组缓冲区,后者则 操作元素数组缓冲区。
drawArrays()和 drawElements()的第一个参数都表示要绘制形状的常量。下面列出了这些常量。
 gl.POINTS:将每个顶点当成一个点来绘制。
 gl.LINES:将数组作为一系列顶点,在这些顶点间绘制直线。每个顶点既是起点也是终点,因
此数组中的顶点必须是偶数个才能开始绘制。
 gl.LINE_LOOP:将数组作为一系列顶点,在这些顶点间绘制直线。从第一个顶点到第二个顶点
绘制一条直线,再从第二个顶点到第三个顶点绘制一条直线,以此类推,直到绘制到最后一个
顶点。此时再从最后一个顶点到第一个顶点绘制一条直线。这样就可以绘制出形状的轮廓。
 gl.LINE_STRIP:类似于 gl.LINE_LOOP,区别在于不会从最后一个顶点到第一个顶点绘制直线。
 gl.TRIANGLES:将数组作为一系列顶点,在这些顶点间绘制三角形。如不特殊指定,每个三角
形都分开绘制,不共享顶点。
 gl.TRIANGLES_STRIP:类似于 gl.TRIANGLES,区别在于前 3 个顶点之后的顶点会作为第三
个顶点与其前面的两个顶点构成三角形。例如,如果数组中包含顶点 A、B、C、D,那么第一个
三角形使用 ABC,第二个三角形使用 BCD。
 gl.TRIANGLES_FAN:类似于 gl.TRIANGLES,区别在于前 3 个顶点之后的顶点会作为第三个
顶点与其前面的顶点和第一个顶点构成三角形。例如,如果数组中包含顶点 A、B、C、D,那么
第一个三角形使用 ABC,第二个三角形使用 ACD。
以上常量可以作为 gl.drawArrays()方法的第一个参数,第二个参数是数组缓冲区的起点索引,
第三个参数是数组缓冲区包含的顶点集合的数量。以下代码使用 gl.drawArrays()在画布上绘制了一 个三角形:

// 假设已经使用本节前面的着色器清除了视口
// 定义3个顶点的x坐标和y坐标
let vertices = new Float32Array([ 0, 1, 1, -1, -1, -1 ]),
        buffer = gl.createBuffer(),
        vertexSetSize = 2,
        vertexSetCount = vertices.length/vertexSetSize,
        uColor,
        aVertexPosition;
// 将数据放入缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 给片段着色器传入颜色
uColor = gl.getUniformLocation(program, "uColor"); gl.uniform4fv(uColor, [ 0, 0, 0, 1 ]);
// 把顶点信息传给着色器
aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); gl.enableVertexAttribArray(aVertexPosition);

接着给顶点着色器传入顶点集的大小,以及表示顶点坐标数值类型的 gl.FlOAT。第四个参数是一 个布尔值,表示坐标不是标准的。第五个参数是步长值(stride value),表示跳过多个数组元素取得下一 个值。除非真要跳过一些值,否则就向这里传入 0 即可。最后一个参数是起始偏移量,这里的 0 表示从 第一个数组元素开始。 18
最后一步是使用 gl.drawArrays()把三角形绘制出来。通过把第一个参数指定为 gl.TRIANGLES, 就可以从(0, 1)到(1, –1)再到(–1, –1)绘制一个三角形,并填充传给片段着色器的颜色。第二个参数表示缓 冲区的起始偏移量,最后一个参数是要读取的顶点数量。以上绘图操作的结果

这个例子定义了一个 Float32Array 变量,它包含 3 组两个点的顶点。完成计算的关键是跟踪顶 点大小和数量。将 vertexSetSize 的值指定为 2,再计算出 vertexSetCount。顶点信息保存在了缓 冲区。然后把颜色信息传给片段着色器。

gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0); // 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, vertexSetCount);

通过改变 gl.drawArrays()的第一个参数,可以修改绘制三角形的方式。图 18-17 展示了修改第
一个参数之后的两种输出。

纹理

WebGL 纹理可以使用 DOM 中的图片。可以使用 gl.createTexture()方法创建新的纹理,然后 再将图片绑定到这个纹理。如果图片还没有加载,则可以创建一个 Image 对象来动态加载。图片加载 27 完成后才能初始化纹理,因此在图片的 load 事件之后才能使用纹理。比如:

let image = new Image(),
  texture;
image.src = "smile.gif";
     image.onload = function() {
      texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// 除当前纹理
      gl.bindTexture(gl.TEXTURE_2D, null);
    }

除了使用 DOM 图片,这些步骤跟在 OpenGL 中创建纹理是一样的。最大的区别在于使用 gl.pixelStorei()设置了像素存储格式。常量 gl.UNPACK_FLIP_Y_WEBGL 是 WebGL 独有的,在基 于 Web 加载图片时通常要使用。原因在于 GIF、JPEG 和 PNG 图片使用的坐标系统与 WebGL 内部的坐 标系统不一样。如果不使用这个标志,图片就会倒过来。
用于纹理的图片必须跟当前页面同源,或者是来自启用了跨源资源共享(CORS,Cross-Origin Resource Sharing)的服务器上。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值