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

news2025/1/16 15:02:25

文章目录

  • 前言
  • 分支和循环
    • if、if-else
    • for
    • continue、break、discard
  • 着色器内置变量
  • 函数
    • 函数定义
    • 规范声明
    • webgl内置函数
  • 存储限定字
    • const
    • attribute
    • uniform
    • varying
  • 精度限定字
  • 预处理指令
  • 总结


前言

本篇接上文继续对着色器语言规范进行讲解,本文的内容包括:分支和循环、着色器内置变量、函数、存储限定字、精度限定字、预处理指令等,接OpenGL ES着色器语言(GLSL ES)规范 ——上篇。


分支和循环

GLSL ES也支持分支循环相关的方法,用法与javascript几乎一致,为数不多的区别是GLSL ES中没有switch关键字,多了discard关键字

if、if-else

if、if-else过多时会影响着色器执行速度,应合理使用。

   // 顶点着色器
	const vertex =  `
		attribute vec4 aPosition;
		varying vec4 vCoord
		void main() {
			vCoord = aPosition;
			gl_Position = aPosition;
			gl_PointSize = 10.0;
		}
	`
	// 片元着色器
	const fragment =  `
		precision highp float;
		varying vec4 vCoord
		void main(){
			if (vCoord.x > 0.5) {
				gl_FragColor = vec4(1.0,1.0,1.0,1.0);
			} else {
				gl_FragColor = vec4(0.0,0.0,0.0,1.0);
			}		
		}
	`

for

	 `
		void main() {
			for (int i = 0; i < 3; i++) {
				sum += i
			}
		}
	`

continue、break、discard

  • continue表示终止当前循环并跳到下一个循环
  • break表示终止当前循环并跳出整个循环
  • discard只能出现在片元着色器中,表示终止处理当前片元跳到下一个片元

着色器内置变量

webgl中内置了一些变量可以直接在着色器中使用:

webgl中的变量类型含义
gl_PointSizefloat绘制点时,正方形的边长
gl_Positionvec4顶点裁剪坐标值
gl_FragColorvec4片元颜色值
gl_FragCoordvec2片元在屏幕上的像素坐标
gl_PointCoordvec2点渲染模式对应点像素坐标

函数

函数定义

函数的定义与C语言的样式很类似,注意除非定义函数时声明了void,否则函数必须有返回值,而且GLSL ES中的函数不允许递归调用(闭包)

// 旋转函数
vec2 rotate(vec2 uv, float rotation, vec2 mid) {
return vec2(cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x, cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y);
}

// 使用该函数
vec2 rotateUv = rotate(vUv,3.14*0.25,vec2(0.5,0.5));
float rbga = 1.0-rotateUv.y;
gl_FragColor =vec4(rbga,rbga,rbga,1);

规范声明

如果函数在其定义前就先被使用也是可以的,这时候要提前对函数进行规范声明

//旋转函数声明
vec2 rotate(vec2, float, vec2) 

// 旋转函数使用
vec2 rotateUv = rotate(vUv,3.14*0.25,vec2(0.5,0.5));
float rbga = 1.0-rotateUv.y;
gl_FragColor =vec4(rbga,rbga,rbga,1);

// 旋转函数定义
vec2 rotate(vec2 uv, float rotation, vec2 mid) {
return vec2(cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x, cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y);
}

webgl内置函数

webgl内部将一些常用的函数开放了出来,函数的返回类型取决于参数类型。

  • 角度函数
名称类型含义
radians()float / vec角度转弧度
degrees()float / vec弧度转角度
  • 三角函数
名称类型含义
sin()float / vec弧度的正弦值
cos()float / vec弧度的余弦值
tan()float / vec弧度的正切值
asin()float / vec反正弦值
acos()float / vec反余弦值
atan()float / vec反正切值
  • 指数函数
名称类型含义
pow(a,n)float / veca的n次方
exp(n)float / vec自然底数e的n次方
log(n)float / vec以e为底n的对数
exp2(n)float / vec2的n次方
log2(n)float / vec以2为底的n的对数
sqrt(n)float / vec对n开平方
inversesqrt(n)float / vec对n开平方并取倒数
  • 通用函数
名称类型含义
abs(x)float / vecx的绝对值
sign(x)float / vecx的绝对值,正数返回1.0,负数返回-1.0,否则返回0.0
floor(x)float / vec向下取整
ceil(x)float / vec向上取整
fract(x)float / vec获取小数部分
mod(x,y)float / vec返回x/y的模
max(x,y)float / vec返回x和y中的较大值
clamp(x,minVal,maxVal)float / vec将一个值限制在一个上限和下限之间,min(max(x, minVal), maxVal)
mix(x,y,r)float / vec线性内插,mix(x,y,r) = (1-r)*x +yr
step(edge,a)float / vec阶梯函数,a<edge返回0.0,否则返回1.0
smoothstep(edge1,edge2,a)float / vec艾米内内插步进,a<edge1返回0.0,a>edge2返回1.0,edge2>a>edge1返回艾米内插值结果
  • 几何函数
名称类型含义
length(v)float矢量v的长度
distance(p0,p1)float返回p0和p1之间的距离
dot(x,y)float返回x和y之间的内积/点乘
cross(x,y)vec返回x和y之间的外积/叉乘
normalize(x)float/vec向量归一化为单位向量
faceforward(N,I,Nref)float/vec法向量反向
reflect(I,N)float/vec根据入射向量I和表面法向量N(单位向量)计算反射向量
refract(I,N,eta)float/vec根据入射向量I和表面法向量N(单位向量),折射率eta计算折射向量
  • 矩阵函数
名称类型含义
matrixCompMult(mat1, mat2)mat2/mat3/mat4矩阵对应位置上的元素相乘,返回新的矩阵
  • 矢量函数
名称类型含义
lessThan(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 < vec2 是否成立
lessThanEqual(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 <= vec2 是否成立
greaterThan(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 > vec2 是否成立
greaterThanEqual(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 >= vec2 是否成立
equal(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 = vec2 是否成立
notEqual(vec1, vec2)bvec2/bvec3/bvec4逐分量比较vec1 != vec2 是否成立
any(vec)boolvec任意分量为true,返回true
all(vec)boolvec全部分量为true,返回true
not(vec)bool逐分量取补
  • 纹理查询函数

sampler2D: 使用纹理坐标coord,从当前绑定到sampIer的二维纹理中读取相应的纹素。对于投影版本(带有Poj的),纹理坐标将从cood的最后一个分量中解析出来,而vec4类型的 coord的第3个分量将被忽略。参数bias只可在片元着色器中使用,它表示在sampIer是 MIPMAP纹理时,加在当前 lod上的值。如下:

名称类型
texture2D(sampler2D sampler,vec2 coord)vec4
texture2D(sampler2D sampler,vec2 coord,float bias)vec4
texture2DProj(sampler2D sampler, vec3 coord)vec4
texture2DProj(sampler2D sampler,vec3 coord, float bias)vec4
texture2DProj(sampler2D sampler,vec4 coord)vec4
texture2DProj(sampler2D sampler,vec4 coord, float bias)vec4
texture2DLod(sampler2D sampler,vec2 coord, float lod)vec4
vec4 texture2DProj(sampler2D sampler,vec4 coord, float bias)vec4
texture2DProjLod(sampler2D sampler,vec3 coord, float lod)vec4
texture2DProjLod(sampler2D sampler,vec4 coord, float lod)vec4

samplerCube: 使用纹理坐标coord,从绑定到sampler的立方体纹理中读取响应纹素。coord的方向可用来指定立方体纹理的表面。如下:

名称类型
textureCube(samplerCube sampler, vec3 coord)vec4
textureCube(samplerCube sampler, vec3 coord, float bias)vec4
textureCubeLod(samplerCube sampler,vec3 coord, float lod)vec4

存储限定字

在GLSL ES中,会经常使用attribute、uniform、varying来传递变量
在这里插入图片描述

const

首先来讲一下const变量,const代表一个不能改变的值,使用const时,需要同时对变量进行声明和初始化

const float PI 3.14; 
const vec4 red  (1.0, 0.0, 0.0, 1.0); 

attribute

attribute变量只能在顶点着色器中使用,它是一个全局变量,被用来表示接收顶点信息

attribute vec3 position; // 存储坐标信息
attribute vec2 uv; // 贴图坐标
attribute vec4 a_Color // 颜色

uniform

uniform变量既可以在顶点着色器中使用,也可以在片元着色器中使用,它也是一个全局变量,可以是除了数组与结构体的任何类型,在顶点着色器和片元着色器定义了同名uniform变量时会被二者共享,即会被所有顶点和片元共用,它可以被用来存储变换矩阵,时间纹理这种影响所有顶点的信息。

uniform mat4 modelMatrix; // 模型转换矩阵
uniform mat4 viewMatrix; // 视图矩阵
uniform mat4 projectionMatrix; // 投影矩阵
uniform float uTime; // 时间

varying

varying它也是一个全局变量,与uniform和attribute不同的是:他不是将javascript中的信息传给着色器,使用时必须同时在顶点着色器和片元着色器中定义同名同类型的varying变量,它的作用是把顶点着色器的数据传递给片元着色器,举例:

在顶点着色器,使用varying定义一个变量v_uv,它是二维向量类型,用它获取每个点的uv坐标

varying vec2 v_uv;
void main() {
  v_uv = uv;
  ···
}

在片元着色器中接收来自顶点着色器中的uv信息,并把它作为rbga中的前俩个值

varying vec2 v_uv;
void main() {
  gl_FragColor = vec4(v_uv, 0.0, 1.0); 
}

精度限定字

在GLSL中需要指定精度以提高运行效率,减少内存损耗,顶点着色器默认指定高精度,片元着色器需手动指定。可以在开头指定以下三个之一。

precision lowp float;
precision mediump float;
precision highp float;

预处理指令

GLSL ES支持预处理指令。预处理指令用来在真正编译之前对代码进行预处理,都以井号(#)开始。GLSL ES提供了三种预处理指令。

  • #if

#if 条件表达式
If 条件表达式为真,执行这里
#endif

  • #ifdef

#ifdef 某宏
如果定义了某宏,执行这里
#endif

  • #ifndef

#ifdef 某宏
如果没有定义某宏,执行这里
#endif

宏的定义使用关键字 #define,解除宏定义使用 #undef
举例:

	#define PI 3.1415926
	#ifdef PI
		precision highp float
	#endif

总结

分支和循环

  • if、if-else
  • for
  • continue、break、discard

着色器内置变量

函数

  • 函数定义
  • 规范声明
  • webgl内置函数

存储限定字

  • const
  • attribute
  • uniform
  • varying

精度限定字

预处理指令

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

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

相关文章

Windows下JetBrains GoLand环境配置记录

闲来无事&#xff0c;go go go 这篇文章不是最简单的配置方法&#xff0c;相对简单的配置方法见文末引用。 本文记录了我遇见的一些问题以及解决方案与解释。 Go编译环境配置 首先得前往谷歌的网站下载go语言的镜像文件&#xff1a; Downloads - The Go Programming Languag…

1. 数据仓库维度建模简介

数据仓库的设计目的软件产品来源于用户的需求&#xff0c;因此&#xff0c;在深入数据仓库的设计之前&#xff0c;我们需要了解客户的痛点有哪些&#xff0c;整理如下&#xff1a;我们收集了海量的数据&#xff0c;但无法对其访问&#xff1b;我们需要以各种方式方便的对数据进…

C C++实现两矩阵相乘--模拟法

目录前言数学中两矩阵怎么相乘?C/C语言实现运行结果前言 11月左右大三找日常实习的时候&#xff0c;面试乱杀&#xff0c;但是笔试碰到了这个矩阵相乘的编程题有几次&#xff0c;可能脑瓜子晕&#xff0c;突然被绕来绕去写不出来&#xff0c;很无语&#xff0c;现在总结一下;…

CS61A 2022 fall lab01

CS61A 2022 fall lab01 文章目录CS61A 2022 fall lab01TopicsDivision, Floor Div, and ModuloFunctionsCall expressionsreturn and printControlBoolean operatorsShorting Circuiting(短路效应)If StatementsWhile LoopsError MessagesRequired QuestionsWhat Would Python …

AI算法(三)plt基础

目录 一、前言 二、各类图 2.1、折线图 2.2、散点图 2.3、点线图 2.4、下三角线 2.5、点虚线 2.6、虚点线 2.7、绘制自己的学习曲线 三、多线 四、画布 五、直方图 一、前言 plt是深度学习的常用库之一&#xff0c;很多指标结果如AUC、F1、ROC等都是通过plt来实现。本篇文章主…

【每日数据结构与算法】

这里面有 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树; 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算 法、动态规划、字符串匹配算法。 文章目录一、 基本算法思想1-1 回溯1-2 动态规划dp1-3二、 排序2-1 O(n…

【015 关键字】typedef和define的区别

一、两者区别 关键字typedefdefine&#xff08;宏&#xff09;作用不同定义&#xff08;标识符或关键字&#xff09;别名简单字符串替换执行时间不同编译过程一部分预处理过程完成作用域不同从定义到花括号“}”截至从定义到文件结尾截止 对指针操作不同 typedef int* INTPTR…

2023啦 最新无人直播小白教程!

最近看了不少up主说&#xff0c;无人直播这个东西可以做副业&#xff0c;自己手里也有一台五年的腾讯云服务器&#xff0c;一个月2t流量&#xff0c;应该是够的&#xff0c;可以玩玩。 先放出我的直播间地址看看效果&#xff1a; b站小红书&#xff08;深度sleep&#xff09;b站…

想要学会二叉树?树的概念与结构是必须要掌握的!快进来看看吧

目录 1.树的概念及结构 1.1什么是树&#xff1f; 1.2树的相关术语 1.3树的表示 2.二叉树的概念及结构 2.1二叉树的概念 2.2两种特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 2.4.1 顺序存储 2.4.2 链式存储 1.树的概念及结构 1.1 什么是树&#xff1f; 树是…

【JavaSE专栏6】Java 基本类型转换、包装类、自动装箱、自动拆箱

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

SpringBoot05:员工管理系统

先不连接数据库&#xff0c;后面整合了mybatis再补充 步骤&#xff1a; 1、导入静态资源 下载地址&#xff1a;下载 - KuangStudy 2、在pojo包下写实体类 ①Department //部门表 Data AllArgsConstructor NoArgsConstructor public class Department {private Integer id;…

IPV4地址详解

文章目录IPV4地址分类编址划分子网无分类编制CIDR路由聚合应用规划&#xff08;子网划分的细节&#xff09;定长的子网掩码FLSM变长的子网掩码VLSMIPV4地址 IPV4地址就是给因特网&#xff08;Internet&#xff09;上的每一台主机&#xff08;或路由器&#xff09;的每一个接口…

恶意代码分析实战 2 动态分析基础技术

2.1 Lab3-1 使用动态分析基础技术来分析在Lab03-01.exe文件中发现的恶意代码。 问题 找出这个恶意代码的导入函数与字符串列表。 C:\Documents and Settings\Administrator>strings Lab03-01.exe ExitProcess kernel32.dll ws2_32 cksu advapi32 ntdll user32 StubPath SO…

39.Isaac教程--使用 Pose CNN 解码器进行 3D 物体姿态估计

使用 Pose CNN 解码器进行 3D 物体姿态估计 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录使用 Pose CNN 解码器进行 3D 物体姿态估计应用概述推理模块Pose CNN 解码器训练模块Pose CNN 解码器架构Pose CNN解码器训练从场景二进制文件生…

JAVA BIO与NIO、AIO的区别

1、 IO模型发展 在Java的软件设计开发中&#xff0c;通信架构是不可避免的&#xff0c;我们在进行不同系统或者不同进程之间的数据交互&#xff0c;或者在高并发下的通信场景下都需要用到网络通信相关的技术&#xff0c;对于一些经验丰富的程序员来说&#xff0c;Java早期的网…

通信原理简明教程 | 现代数字调制

文章目录1 多进制基带信号2 多进制数字调制2.1 多进制调制的基本原理2.2 MPSK调制3 MSK3.1 MSK信号的表示3.2 MSK的相位网格图3.3 MSK的产生和解调4 QAM4.1 QAM的基本原理4.2 QAM信号的产生和解调4.3 QAM信号的特性5 正交频分复用5.1 OFDM的基本思想5.2 OFDM的基本原理5.3 基于…

Python基础学习 -- 常用模块

一、time模块1、时间戳可以理解为是一个计算机世界的当前时间&#xff0c;很多加密验证什么的&#xff0c;都会用到import time ttime.time() print(int(t)) 运行结果&#xff1a; 16732534522、当前时间import time ttime.strftime("%Y-%m-%d %X") print(t) 运行结果…

vue项目搭建(offline方式)

项目搭建的前提 需要安装node.js&#xff0c;安装步骤可参考https://blog.csdn.net/qq_44628230/article/details/122634132 1.检查环境是否已准备好 2.全局安装vue-cli 3.进入到项目目录&#xff0c;创建一个基于 webpack 模板的新项目&#xff08;online&#xff09; 4.由…

JavaScript笔记+案例

前端开发 第四节JavaScript JavaScript&#xff1a;概要 概要&#xff1a; JavaScript&#xff0c;是一门编程语言。浏览器就是JavaScript语言的解释器。 DOM和BOM 相当于编程语言内置的模块。 例如&#xff1a;Python中的re、random、time、json模块等。jQuery 相当于是编程…

搭建代理服务器

搭建代理服务器搭建代理服务器场景ccproxy进行搭建代理服务器proxifier配置代理服务器总结搭建代理服务器 有这种情况&#xff0c;在家需要访问某个内网环境&#xff0c;但是内网的ip从外网是访问不到的&#xff0c;这种需要怎么处理呢&#xff1f; 答案是使用代理服务器。 …