OpenGL ES着色器语言(GLSL ES)规范 ——上篇


前言

着色器语言通过控制GPU来进行前端图形的渲染,WebGL使用名为GLSL ES的规范进行着色器语言的编写,GLSL ES是在OpenGL的基础上进行一定的精简后形成的,它的语法与C语言有些类似。 本文对webgl常用到的GLSL ES知识进行记录。
着色器以字符串的形式存储在javascript中


OpenGL ES基础

一段基本的着色器代码

   // 顶点着色器
	const vertex =  `
		attribute vec4 aPosition;
		void main() {
			gl_Position = aPosition;
			gl_PointSize = 10.0;
		}
	`
	// 片元着色器
	const fragment =  `
		precision highp float;
		uniform vec4 uColor;
		void main(){
			gl_FragColor = uColor;
		}
	`

大小写和分号

  • 大小写敏感
const vertex =  `
		// 不会报错,aPosition和aposition是两个不同的变量
		attribute vec4 aPosition;
		attribute vec4 aposition;
		void main() {
			gl_Position = aPosition;
			gl_PointSize = 10.0;
		}
	`
  • 强制分号
const vertex =  `
		attribute vec4 aposition  // 运行会报错
		void main() {
			gl_Position = aPosition;
			gl_PointSize = 10.0;
		}
	`
  • 执行次序

着色器的执行从main函数开始逐行运行,无论是顶点着色器还是片元着色器都有且只有一个main函数作为整个程序的入口,该函数由void声明,不接受任何参数,也没有返回值

  • 注释

着色器的注释与js相同, // 进行单行注释;/* xxx */ 进行多行注释。

数据值类型、命名规范、类型转换

GLSL 是强类型语言,数据声明时必须指定类型。GLSL支持整形(int),浮点型(float),布尔(bool)三种数据类型。

const vertex =  `
		void main() {
			int ten = 10; // 整型
			float pie = 3.14; // 浮点型
			bool isOk = true; // 布尔型
			
			gl_Position = aPosition;
			gl_PointSize = 10.0;
		}
	`

变量的命名需要遵守以下规则:

  • 只包括a-z,A-Z,0-9,_,无其它特殊字符
  • 首位不能是数字
  • 不能以gl_、webgl_、_webgl_开头
  • 避免与webgl内置关键字或者保留字重名

不同类型的变量之间不能直接相互赋值,但是通过内置函数进行类型转换后可以:

名称参数类型含义
int ( x )float / bool转换为整数
float ( x )int / bool转换为小数
bool ( x )float / int转换为布尔

运算符

在这里插入图片描述

矢量和矩阵

矢量和矩阵类型

类型GLSL ES类型含义
矢量vec2、vec3、vec4长度为2、3、4,元素类型为float的矢量
矢量ivec2、ivec3、ivec4长度为2、3、4,元素类型为int的矢量
矢量bvec2、bvec3、bvec4长度为2、3、4,元素类型为bool的矢量
矩阵mat2、mat3、mat4维度为2 * 2、3 * 3、4 * 4,元素类型为float的矩阵

矢量构造、访问

  • 矢量构造函数赋值
const vertex =  `
		void main() {
			vec4 vector4 = vec4(1.0, 1.0, 1.0, 1.0); // 普通赋值
			vec4 vector4_copy = vec4(vector4); // 复制
			vec2 vector2 = vec2(vector4); // 取vector4前两个值组成矢量
			vec4 vector4_copy2 = vec4(2.0); // vec4(2.0, 2.0, 2.0, 2.0)
			vec4 vector4_new = vec4(vector2, vector2); // 组装成一个vec4
			
			···
		}
	`
  • 矢量访问

可以通过 . 进行访问

const vertex =  `
		void main() {
			vec4 vector4 = vec4(1.0, 2.0, 3.0, 1.0); // 普通赋值
			
			float v1 = vector4.x  // 1.0
			vec2 v2 = vector4.xy  // vec2(1.0, 1.0)
			vec2 v2_ = vector4.zx  // vec2(3.0, 1.0)
			···
		}
	`

也可以通过 [ ] 获取下标进行访问

const vertex =  `
		void main() {
			vec4 vector4 = vec4(1.0, 2.0, 3.0, 1.0); // 普通赋值
			
			float v1 = vector4[0]  // 1.0
		}
	`

矩阵构造、访问

  • 矩阵赋值

矩阵传入值必须是列主序的

在这里插入图片描述
像上面整个矩阵,赋值方式如下:

mat m4 = (
	a,  e,  i,  m,
    b,  f,  j,  n,
    c,  g,  k,  o,
    d,  h,  l,  p
)
// 或者
vec4 vec1 = (a,  e,  i,  m)
vec4 vec2 = (b,  f,  j,  n)
vec4 vec3 = (c,  g,  k,  o)
vec4 vec4 = (d,  h,  l,  p)

mat4 m4 = mat4(vec1, vec2, vec3, vec4)
  • 矩阵访问

可以通过 . 和 [ ] 进行访问

const vertex =  `
		void main() {
			vmat m4 = (
				a,  e,  i,  m,
   				b,  f,  j,  n,
    			c,  g,  k,  o,
    			d,  h,  l,  p
			)

			vec4 v4_ = vector4[3];  // [m, n, o, p]
			float v4_2 = vector4[3][1] ; // n
			vec4 v4_2 = vector4[3].y;  // n
			···
		}
	`

矢量矩阵运算规则

  • 当矩阵之间进行计算时(+ 、- 、* 、/),遵从矩阵运算规则
  • 矢量之间进行计算时(+ 、- 、* 、/),对应位置上的元素进行相应计算
  • 矩阵矢量之间进行计算时(* 、/),当向量在左,计算规则按照1 * n的矩阵与n阶矩阵相乘;当向量在右边,按照n阶矩阵与n*1的矩阵相乘

特殊类型—结构体和数组

结构体

GLSL ES支持使用结构体来创建用户自定义的类型,与C++十分类似:

// 定义结构体pen
struct pen {
	vec4 color;
	float lenght;
}
// 声明pen类型的对象
pen pen1, pen2;
// 给结构体赋值
pen1 = pen(vec4(1.0,0.0,0.0,1.0, 10.1);
// 访问结构体
vec4 pen1_color = pen1.color;
float pen1_length = pen1.length;

数组

GLSL ES同时也支持数据类型,但是仅支持一维数组,数组不支持pop()和push()操作,数组不能一次性初始化,必须显式地对每个元素初始化

// 声明数组
float floatArray[4]; // 元素类型是float,长度是4的数组
vec4 vec4Array[2]; // 元素类型是vec4,长度是2的数组

// 数组赋值
floatArray[0] = 0.0;
floatArray[1] = 1.0;
floatArray[2] = 2.0;
floatArray[3] = 3.0;

vec4Array[0] = (0.0,0.0,0.0,0.0);
vec4Array[1] = (1.0,1.0,1.0,1.0);

取样器

GLSL ES支持一种名为取样器(sampler的变量类型获取纹理,取样器变量必须是uniform变量,取样器支持两种类型sampler2D和samplerCube,sampler2D的使用见webgl纹理贴图机制,samplerCube是立方体纹理,使用和sampler2D差不多,唯一区别就是在使用gl.texImage2D()进行图像分配给纹理对象时,要把六个面的数据都分配一次。

总结

OpenGL ES基础

  • 一段基本的着色器代码
  • 大小写和分号
  • 数据值类型、命名规范、类型转换
  • 运算符

矢量和矩阵

  • 矢量和矩阵类型
  • 矢量构造、访问
  • 矩阵构造、访问
  • 矢量矩阵运算规则

特殊类型—结构体和数组

  • 结构体
  • 数组

取样器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值