博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenGL ES 编程基础(三)
阅读量:4297 次
发布时间:2019-05-27

本文共 2013 字,大约阅读时间需要 6 分钟。

OpenGL ES 着色语言基础

预处理器和指令

OpenGL ES 着色语言中配备的预处理器遵循大多标准 C++ 预处理器的约定,如下面的宏指令和条件测试:

#define#undef#if#ifdef#ifndef#else#elif#endif

OpenGL ES 着色语言中不支持含有参数的宏定义

  • __LINE__ 表示着色器中的行号
  • __FILE__ 表示文件名,但在 OpenGL ES 3.0 中为 0
  • __VERSION__ 表示着色语言版本,如 300
  • GL_ES 表示着色器中的 1

除了 #error #pragma 还有重要的 #extension 指令,用于启用和设置扩展的行为。

设置某一个扩展的行为:#extension <扩展名> : <行为>

设置所有扩展的行为:#extension all : <行为>

可选择的扩展行为如下:

扩展行为 说明
require 表示扩展是必须的,所以预处理器在扩展不受支持时将抛出错误,
如果指定 all 为这种行为,则始终抛出错误
enable 表示启用扩展,如果不支持,预处理器将抛出警告,否则就处理该扩展,
如果指定 all 为这种行为,则始终抛出错误
warn 使用扩展时抛出警告,除非该扩展是另一个启用的扩展所必须的,
如果指定 all ,那么使用任何扩展时都会抛出警告,即使扩展不被支持,也会抛出警告
disable 禁用扩展,若使用则抛出错误,
如果指定 all(默认)则不启用任何扩展

统一变量及插值器打包

由于硬件的限制,统一变量及插值器的存储空间是宝贵的,所以合理使用存储空间十分必要。在 OpenGL ES 3.0 中,为了更好的利用空间,采用打包规则将插值器和统一变量映射到物理存储空间中。

打包规则基于物理存储空间被组织为一个每个存储位置4列和1行的网格的概念,这里可以连系到矩阵的默认列优先存储。如下面的例子,可看出打包与未打包之间的区别。

uniform mat3 m;uniform float f[6];uniform vec3 v;

如下是未进行打包的统一变量存储

存储位置 X Y Z W
0 m[0].x m[0].y m[0].z -
1 m[1].x m[1].y m[1].z -
2 m[2].x m[2].y m[2].z -
3 f[0] - - -
4 f[1] - - -
5 f[2] - - -
6 f[3] - - -
7 f[4] - - -
8 f[5] - - -
9 v.x v.y v.z -

如下是进行了打包的统一变量存储

存储位置 X Y Z W
0 m[0].x m[0].y m[0].z f[0]
1 m[1].x m[1].y m[1].z f[1]
2 m[2].x m[2].y m[2].z f[2]
3 v.x v.y v.z f[3]
4 - - - f[4]
5 - - - f[5]

可见,使用打包后,节省了4个物理常量位置,需要注意的是,数组的元素必须跨越行边界进行存储,因为 GPU 通常是按照向量位置索引对常量存储进行索引,所以要使索引有效,需要数组元素跨越行边界。

虽然打包是对 OpenGL ES 语言使用者是透明的,但是打包会影响统一变量和插值器的计数方式,这就关系着着色器最终所需的运行存储空间,所以要编写可移植的着色器,这个所需的运行存储不应超过 OpenGL ES 3.0 所支持的最小存储空间。

精度限定符

在着色器中指定变量的计算精度,有助于着色器的运行并可以节约电量,但也可能因精度不够导致伪像。

精度关键字有:highp mediump lowp,分别表示高、中、低三个精度。

highp vec4 position;varying lowp vec4 color;mediump float pi;

另外可以指定变量类型的默认精度

precision highp float;precision mediump int;

顶点着色器中的默认精度是最高的 highp ,但是在片段着色器中 float 没有默认精度,需要自己指定。当然,指定的精度的表示范围在不同的硬件上可能是不同的。

不变性

编译器在编译着色器时,可能会对指令进行重排优化,这就意味着相同的输入参数及计算条件可能会得到两个不同的结果。如在使用 Alpha 混合绘制时,可能因为计算的输出位置精度不一致而导致伪像,即深度冲突(Z fighting)。

所以为了避免类似的情况,可以使用 invariant 关键字将输出变量声明为不可变,那么编译器将保证在相同计算和着色器输入条件下,输出结果是相同的。

invariant gl_Position;

另外,还可以指定所有变量的不可变性:#pragma STDGL invariant(all) ,但是这会导致性能下降。

转载地址:http://dadws.baihongyu.com/

你可能感兴趣的文章
python绘制k线图(蜡烛图)报错 No module named 'matplotlib.finance
查看>>
talib均线大全
查看>>
期货市场技术分析06_长期图表和商品指数
查看>>
期货市场技术分析07_摆动指数和相反意见理论
查看>>
满屏的指标?删了吧,手把手教你裸 K 交易!
查看>>
不吹不黑 | 聊聊为什么要用99%精度的数据回测
查看>>
X 分钟速成 Python
查看>>
对于模拟交易所引发的思考
查看>>
高频交易的几种策略
查看>>
网格马丁格尔交易法
查看>>
一行代码让 Python 的运行速度提高100倍
查看>>
一行 Python 实现并行化 -- 日常多线程操作的新思路
查看>>
期货市场的运作机制
查看>>
一文精通 crontab从入门到出坑
查看>>
股票连续跌停后开板表现
查看>>
东航期货行情接口和交易接口(20190509)
查看>>
ubnutu系统完美克隆至新硬盘,系统备份迁移至新硬盘
查看>>
ubnutu系统完美克隆至新硬盘,系统备份迁移至新硬盘
查看>>
东航期货模拟交易brockerid(期货公司的客户号)
查看>>
史上最全量化资源整理
查看>>