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

news2025/1/16 8:02:18

文章目录

  • 前言
  • OpenGL 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基础

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

矢量和矩阵

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

特殊类型—结构体和数组

  • 结构体
  • 数组

取样器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/178479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《深入浅出计算机组成原理》学习笔记 Day10

浮点数与定点数1. 浮点数的不精确性2. 定点数的表示3. 浮点数的表示参考1. 浮点数的不精确性 32 比特只能表示 2 的 32 次方个不同的数,差不多是 40 亿个。如果表示的数超过能表示总的个数,那么就会有两个不同的数的二进制表示是一样的。计算机就会不知…

【深度学习炼丹】不平衡样本的处理

目录:不平衡样本的处理一、前言二、数据层面处理方法2.1 数据扩充2.2 数据(重)采样2.3 类别平衡采样三、算法(损失函数)层面处理方法3.1 Focal Loss3.2 损失函数加权四、参考资料一、前言 在机器学习的经典假设中往往…

VMWare 移动Linux CentOS 7虚拟机后连不上网怎么办

研究hadoop的时候发现虚拟机太大了,于是把3台节点的虚拟机剪切粘贴到移动硬盘上,但是出现了上不了网的问题 VMWare 移动Linux CentOS 7虚拟机后连不上网,ifconfig命令只出现lo不出现有IP地址的ens33,jps命令也出现了jps command …

机器学习模型搭建与评估

模型搭建和评估第三章 模型搭建和评估--建模模型搭建任务一:切割训练集和测试集任务二:模型创建任务三:输出模型预测结果第三章 模型搭建和评估-评估模型评估任务一:交叉验证任务二:混淆矩阵任务三:ROC曲线…

python爬虫学习笔记-mysql数据库介绍下载安装

数据库概述 为什么要使用数据库? 那我们在没有学习数据库的时候,数据存放在json或者磁盘文件中不也挺好的嘛,为啥还要学习数据库? 文件中存储数据,无法基于文件直接对数据进行操作或者运算,必须借助python将…

IDEA搭建Finchley.SR2版本的SpringCloud父子基础项目-------Ribbon负载均衡

1.概念 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配…

Python闭包与闭包陷阱

1 什么是闭包 在 Python 中,闭包是一种特殊的函数,它能够记住它所在的环境(也称作上下文)。这意味着闭包能够访问定义它的作用域中的变量。闭包通常用于封装数据和提供对外部访问的接口。 在 Python 中使用闭包有以下几点好处&a…

数据库和SQL概述

数据库和SQL概述 数据库的好处 实现数据的持久化使用完整的管理系统统一管理,易于查询 常用的一些名称缩写 DB:数据库(Database):存储数据的“仓库”。它保存了一系列有组织的数据DBMS:数据库管理系统(Database Management Sy…

离线用户召回定时更新

3.6 离线用户召回定时更新 学习目标 目标 知道离线内容召回的概念知道如何进行内容召回计算存储规则应用 应用spark完成离线用户基于内容的协同过滤推荐 3.6.1 定时更新代码 完整代码 import os import sys # 如果当前代码文件运行测试需要加入修改路径,否则后面…

游戏启动器:LaunchBox Premium with Big Box v13.1

LaunchBox知道您会喜欢的功能,具有风格的游戏启动器,我们最初将 Launchbox 构建为 DOSBox 的一个有吸引力的前端,但它现在拥有对现代游戏和复古游戏模拟的支持。我们让您的所有游戏看起来都很漂亮。 整理您的游戏收藏 我们不仅漂亮&#xff…

基于微信小程序奶茶店在线点餐下单系统

奶茶在线下单系统用户端是基于微信小程序端,管理员端是基于web端,基于java编程语言,mysql数据库,idea工具开发,用户微信端可以注册登陆小程序,查看奶茶详情,搜索下单奶茶,在线奶茶评…

CSS @property(CSS 自定义属性)

CSS property(CSS 自定义属性)参考描述propertyHoudiniproperty兼容性描述符规则syntax扩展initial-valueinherits示例描述符的注意事项使用 JavaScript 来创建自定义属性CSS 变量与自定义属性重复赋值过渡简单的背景过渡动画更复杂的背景过渡动画错误示…

【ARM体系结构】之数据类型约定与工作模式

1、RISC和CISC的区别 1.1 RISC : 精简指令集 使用精简指令集的架构:ARM架构 RISC-V架构 PowerPC架构 MIPS架构ARM架构 :目前使用最广泛的架构,ARM面向的低端消费类市场RISC-V架构 :第五代,精简指令集的架构&#xff…

这样定义通用人工智能

🍿*★,*:.☆欢迎您/$:*.★* 🍿 正文 人类解决问题的途径,大体可以分为两种。一种是事实推理,另一种是事实验证。 为什么只是两种分类,因为根据和环境的交互与否。 事实推理解释为当遇到事件发生的时候,思考的过程。可以使用概率模型,或者更复杂的模型(目前没…

Out of Vocabulary处理方法

Out of Vocabulary 我们在NLP任务中一般都会有一个词表,这个词表一般可以使用一些大牛论文中的词表或者一些大公司的词表,或者是从自己的数据集中提取的词。但是无论当后续的训练还是预测,总有可能会出现并不包含在词表中的词,这…

(教程)如何在BERT模型中添加自己的词汇(pytorch版)

来源:投稿 作者:皮皮雷 编辑:学姐 参考文章: NLP | How to add a domain-specific vocabulary (new tokens) to a subword tokenizer already trained like BERT WordPiece | by Pierre Guillou | Medium https://medium.com/pi…

ROS2机器人编程简述humble-第三章-BUMP AND GO IN C++ .3

简述本章项目,参考如下:ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1流程图绘制,参考如下:ROS2机器人编程简述humble-第三章-COMPUTATION GRAPH .2然后,在3.3和3.4分别用C和Python编程实现&am…

Bus Hound 工具抓取串口数据(PC端抓取USB转串口数据)

测试环境: PC端 USB转串口 链接终端板卡串口 目标:抓取通信过程中的通信数据 工具介绍:Bus Hound是是由美国perisoft公司研制的一款超级软件总线协议分析器,它是一种专用于PC机各种总线数据包监视和控制的开发工具软件&#xff0c…

通信原理简明教程 | 数字调制传输

文章目录1 二进制数字调制和解调1.1 二进制数字调制的基本原理1.2 二进制数字调制信号的特性1.3 解调方法2 二进制差分相移键控2.1 2PSK的倒π现象2.2 2DPSK调制和解调3 二进制调制系统的抗噪性能3.1 2ASK系统的抗噪声性能3.2 2FSK系统的抗噪声性能4 二进制数字调制系统性能比较…

服务器配置定时脚本 crontab + Python;centos6或centos 7或centos8 实现定时执行 python 脚本

一、crontab的安装 默认情况下,CentOS 7中已经安装有crontab,如果没有安装,可以通过yum进行安装。 yum install crontabs 二、crontab的定时语法说明 corntab中,一行代码就是一个定时任务,其语法结构可以通过这个图来理解。 字符含义如下: * 代表取值范围内的数字 /…