英文原文:http://iflash3d.com/shaders/my-name-is-agal-i-come-from-adobe-1/
试想有一天,人类灭绝。
试想一下,所有的纸质文件随着时间的推移,变得破旧且无法读,最终都消失了。
想象一下,一些外星物种找到了人类的DVD或固态存储器,包含了一些人类的信息。
他们会如何解读呢?他们如何找到钥匙打开这些“神器”,了解到其中包含了什么样信息呢?
就算他们得到了我们的技术成果,又如何能够真正了解我们的发现和使用我们的技术呢?
是否他们需求这些技术本身能自我解读?
Adobe最近推出了新的语言AGAL(Adobe图形汇编语言)。它是Molehill的一部分,其目的是为了创建所谓的 “着色器(shaders)”:很小的程序,它会作用于3D模型在场景中的渲染。
这些着色器很酷。能达到惊人的渲染效果,编写代码也比ActionScript更难。
这是AGAL的样子:
//vertex shader
m44 op, va0, vc0 // pos to clipspace
mov v0, va1 // copy uv
//pixel shader
tex ft1, v0, fs0 <2d,linear,nomip>
mov oc, ft1
是不是特别像看天书?什么是访问它的关键?
问题是现阶段AGAL相关文档还很少,那么我尝试着来阐明这神秘的着色语言吧。
操作码
着色器的每一行是由 3 个字符的字符串指定的命令行,称为“操作码”。
一个AGAL行代码的语法如下:
<opcode> <destination> <source 1> <source 2 or sampler>
这是关键。记住此语法,AGAL会突然停止看起来像一个不可读的斑点。
操作码(opcode)之后,可以是取决于该命令的目标,和一个或两个源(source)。
目标和源是“寄存器”:GPU中的小小内存区域,供着色器使用(下面有更多的寄存器)。
AGAL约30种不同功能的操作码。在Molehill的文档中可发现可用操作码(opcodes)的完整列表,下面是一些最常见的操作码。
- mov 移动数据从source1到目的地,按分量(点积)
- add destination = source1 + source2,按分量(点积)
- sub destination = source1 – source2,按分量(点积)
- mul destination = source1 * source2,按分量(点积)
- div destination = source1 / source2,按分量(点积)
- dp3 dot product (3 components) between source1 and source2
- dp4 dot product (4 components) between source1 and source2
- m44 multiplication between 4 components vector in source1 and 4×4 matrix in source2
- tex texture sample. Load from texture at source2 at coordinates source1.
AGAL寄存器
寄存器是在GPU的AGAL程序(着色器)执行期间使用的小内存区域。
寄存器同时用于AGAL命令的源与目标。
你也可以传递参数给你的着色器通过这些寄存器。
每个寄存器为128位,这意味着它包含4个浮点值。这些值被称为寄存器的“组件”。
寄存器组件可以通过坐标(xyzw)访问
<register name>.x
也可以通过颜色(rgba)访问
<register name>.r
上述的一些操作码,如“新增”,按点积执行自己的操作。这意味着,加法运算是由组件的组件执行。
这里有六个可用的寄存器类型。
1。属性寄存器
这些寄存器参考顶点着色器的VertexBuffer输入。因此,他们只能在顶点着色器中可用。
要通过正确的索引分配一个VertexBuffer到一个特定的属性寄存器,使用方法
Context3D:setVertexBufferAt()
在着色器中,访问属性寄存器的语法:va<n>,其中<n>是属性寄存器的索引号。
有一共有8个属性寄存器用于顶点着色器。
2。常量寄存器
这些寄存器是用来从ActionScript传递参数到着色的。这是通过Context3D::setProgramConstants()系列函数来实现。
在着色器中,这些寄存器的访问语法:
vc<n>,用于顶点着色器
fc<n>,用于像素着色器
其中<n>是常量寄存器的索引值。
有128个常量寄存器用于顶点着色器和28常量寄存器用于像素着色器。
3。临时寄存器
这些寄存器在着色器中,可以用于临时计算。
这些寄存器的访问语法:
vt<n> (vertex),用于顶点着色器
ft<n> (pixel),用于像素着色器
<n>是寄存器编号。
有8个用于顶点着色器,8个用于像素着色器。
4。输出寄存器
输出寄存器是在顶点和像素着色器存储其计算输出。此输出用于顶点着色器是顶点的剪辑空间位置。用于像素着色器是该像素的颜色。
访问这些寄存器运算的语法:
op,用于顶点着色器
oc,用于像素着色器
但显然只能一个输出寄存器用于顶点和像素着色器。
5。变寄存器
这些寄存器用来从顶点着色器传递数据到像素着色器。传递数据被正确地插入图形芯片,从而使像素着色器接收到正确的正在处理的像素的值。
以这种方式获取传递的典型数据是顶点颜色,或 纹理UV 坐标。
这些寄存器可以被访问的语法v <n>,其中<n>是寄存器编号。
有8个变寄存器可用。
6。纹理取样器
纹理采样寄存器是用来基于UV坐标从纹理中获取颜色值。
纹理是通过ActionScriptcall指定方法Context3D::setTextureAt()。
纹理样本的使用语法是:ft<n> <flags>,其中<n>是取样指数,<flags>是由一个或多个标记,用于指定如何进行采样。
<flags>是以逗号分隔的一组字符串,它定义:
纹理尺寸。可以是:二维,三维,多维数据集
纹理映射。可以是:nomip,mipnone,mipnearest,mipnone
纹理过滤。可以是:最近点采样,线性
纹理重复。可以是:重复,包装,夹取。
因此,举例来说,一个标准的2D纹理没有纹理映射,并进行线性过滤,可以进行采样到临时寄存器FT1,使用以下命令:
“tex ft1, v0, fs0 <2d,linear,nomip> “变寄存器v0持有插值的纹理 UVs。
顶点和像素着色器例子解析
让我们回到我们的着色器的例子,并解释其运作
翻译未完,待续。。。