iOS Metal语言规范(一)

一.Metal简述

            Metal着色器语言是用来编写3D图形渲染逻辑、并行Metal计算核心逻辑的一门编程语言,当你使用Metal框架来完成APP的实现时则需要使用Metal编程语言。

            Metal语言使用Clang 和LLVM进行编译处理,编译器对于在GPU上的代码执行效率有更好的控制

            Metal基于C++ 11.0语言设计的,在C++基础上多了一些扩展和限制,主要用来编写在GPU上执行的图像渲染逻辑代码以及通用并行计算逻辑代码

            Metal 像素坐标系统:Metal中纹理 或者 帧缓存区attachment的像素使用的坐标系统的原点是左上角

1.1Metal 语⾔中不⽀持之处 

        Lambda 表达式;

        递归函数调⽤

        动态转换操作符

        类型识别

        对象创建new 和销毁delete 操作符;

        操作符 noexcept

        goto 跳转

        变量存储修饰符register 和 thread_local;

        虚函数修饰符;

        派⽣类

        异常处理

        C++ 标准库在Metal 语⾔中也不可使⽤;

1.2Metal 语⾔中对于指针使⽤的限制

        Metal图形和并⾏计算函数⽤到的⼊参数; 如果是指针必须使⽤地址空间修饰符(device,threadgroup,constant)

        不⽀持函数指针;

        函数名不能出现main

二.Metal的数据类型及语法

2.1     Metal 数据类型--标量数据类型 

        bool 布尔类型, true/false

        char 有符号8位整数;

        unsigned char /uchar ⽆符号8-bit 整数;

        short 有符号16-bit整数;

        unsigned short / ushort ⽆符号32-bit 整数;

        half 16位bit 浮点数;

        float 32bit 浮点数;

        size_t 64 ⽆符号整数;

        void 该类型表示⼀个空的值集合

说明:其中half 相当于OC中的float,float 相当于OC中的doublesize_t用来表示内存空间, 相当于 OC中 sizeof

示例:boola=true;charb=5;intd=15;//用于表示内存空间size_t c=1;ptrdiff_t f=2;

2.2Metal向量

        向量支持如下类型:- booln、charn、shortn、intn、ucharn、ushortn、uintn、halfn、floatn,其中 n 表示向量的维度,最多不超过4维向量示例:

        //直接赋值初始化

        bool2 A={1,2}

        ;//通过内建函数float4初始化

        float4 pos=float4(1.0,2.0,3.0,4.0);

        //通过下标从向量中获取某个值

        floatx=pos[0];floaty=pos[1];

        //通过for循环对一个向量进行运算

        float4 VB;

        for(inti=0;i<4;i++){

            VB[i]=pos[i]*2.0f;

        }

        说明:在OpenGL ES的GLSL语言中,例如2.0f,在着色器中书写时,是不能加f,写成2.0,而在Metal中则可以写成2.0f,其中f可以是大写,也可以是小写

向量的访问规则:

1.通过向量字母获取元素: 向量中的向量字母仅有2种,分别为xyzw、rgba

        int4 test=int4(0,1,2,3);

        inta=test.x; //获取的向量元素0

        intb=test.y; //获取的向量元素1

        intc=test.z; //获取的向量元素2

        intd=test.w;//获取的向量元素3

        inte=test.r; //获取的向量元素0

        intf=test.g;//获取的向量元素1

        intg=test.b; //获取的向量元素2

        inth=test.a; //获取的向量元素3

2.多个分量同时访问

        float4 c;

        c.xyzw=float4(1.0f,2.0f,3.0f,4.0f);

        c.z=1.0f

        c.xy=float2(3.0f,4.0f);

        c.xyz=float3(3.0f,4.0f,5.0f);

        说明:赋值时分量不可重复,取值时分量可重复右边是取值 和 左边赋值都合法xyzw与rgba不能混合使用,GLSL中向量不能乱序访问,只是和Metal中的向量相似,并不是等价。

示例代码

2.3矩阵

        矩阵支持如下类型- halfnxm、floatnxm,其中 nxm表示矩阵的行数和列数,最多4行4列,其中half、float相当于OC中的float、double- 普通的矩阵其本质就是一个数组

        float4x4 m;

        //将第二行的所有值都设置为2.0

        m[1]=float4(2.0f);

        //设置第一行/第一列为1.0f

        m[0][0]=1.0f;

        //设置第三行第四列的元素为3.0f

        m[2][3]=3.0f;

        float4 类型向量的构造方式

        1个float构成,表示一行都是这个值

        4个float构成

        2个float2构成

        1个float2+2个float构成(顺序可以任意组合)

        1个float2+1个float

        1个float4

eg:

        //float4类型向量的所有可能构造方式//1个一维向量,表示一行都是xfloat4(floatx);

        ///4个一维向量 --> 4维向量float4(floatx,floaty,floatz,floatw);

        //2个二维向量 --> 4维向量float4(float2 a,float2 b);

        //1个二维向量+2个一维向量 --> 4维向量float4(float2 a,float b,float c);

        float4(floata,float2 b,floatc);float4(floata,floatb,float2 c);

        //1个三维向量+1个一维向量 --> 4维向量float4(float3 a,floatb);float4(floata,float3 b);

//1个四维向量 --> 4维向量float4(float4 x);

float3 类型向量的构造方式

        1个float构成,表示一行都是这个值

        3个float

        1个float+1个float2(顺序可以任意组合)

        1个float2

eg:

        //float3类型向量的所有可能的构造的方式

        //1个一维向量float3(floatx);

        //3个一维向量float3(floatx,floaty,floatz);

        //1个一维向量 + 1个二维向量float3(floata,float2 b);

        /1个二维向量 + 1个一维向量float3(float2 a,floatb);

        //1个三维向量float3(float3 x);

        float2 类型向量的构造方式

 1个float构成,表示一行都是这个值

        2个float

        1个float2

eg:

        //float2类型向量的所有可能的构造方式

        //1个一维向量float2(floatx);

        //2个一维向量float2(floatx,floaty);

        //1个二维向量float2(float2 x);

三,Metal的其他类型


1.纹理

纹理类型

纹理类型是一个句柄,指向一维/二维/三维纹理数据,而纹理数据对应一个纹理的某个level的mipmap的全部或者一部分

纹理的访问权限

在一个函数中描述纹理对象的类型

access枚举值由Metal定义,定义了纹理的访问权利enum class access {sample, read, write};,有以下3种访问权利,当没写access时,默认的access 就是sample

sample: 纹理对象可以被采样(即使用采样器去纹理中读取数据,相当于OpenGL ES的GLSL中sampler2D),采样一维这时使用 或者 不使用都可以从纹理中读取数据(即可读可写可采样)

read:不使用采样器,一个图形渲染函数或者一个并行计算函数可以读取纹理对象(即仅可读)

write:一个图形渲染函数 或者 一个并行计算可以向纹理对象写入数据(即可读可写)

定义纹理类型

描述一个纹理对象/类型,有以下三种方式,分别对应一维/二维/三维,

其中T代表泛型,设定了从纹理中读取数据 或是 写入时的颜色类型,T可以是half、float、short、int等

access表示纹理访问权限,当access没写时,默认是sample

texture1d<T, access a = access::sample>

texture2d<T, access a = access::sample>

texture3d<T, access a = access::sample>

eg:

//类型 变量 修饰符

/*

类型

    - texture2d<float>,读取的数据类型是float,没写access,默认是sample

    - texture2d<float,access::read>,读取的数据类型是float,读取的方式是read

    - texture2d<float,access::write>,读取的数据类型是float,读取的方式是write

变量名

    - imgA

    - imgB

    - imgC

修饰符

    - [[texture(0)]] 对应纹理0

    - [[texture(1)]] 对应纹理1

    - [[texture(2)]] 对应纹理2

*/函数举例

void foo (texture2d<float> imgA[[texture(0)]],

          texture2d<float,access::read> imgB[[texture(1)]],

          texture2d<float,access::write> imgC[[texture(2)]])

{

    //...

}

2.采样器

        采样器类型决定了如何对一个纹理进行采样操作,在Metal框架中有一个对应着色器语言的采样器的对象MTLSamplerState,这个对象作为图形渲染着色器函数参数或是并行计算函数的参数传递,有以下几种状态:

coord:从纹理中采样时,纹理坐标是否需要归一化

enum class coord { normalized, pixel };

filter:纹理采样过滤方式,放大/缩小过滤方式

enum class filter { nearest, linear };

min_filter:设置纹理采样的缩小过滤方式

enum class min_filter { nearest, linear };

mag_filter:设置纹理采样的放大过滤方式

enum class mag_filter { nearest, linear };

s_address、t_address、r_address:设置纹理s、t、r坐标(对应纹理坐标的x、y、z)的寻址方式

s坐标:enum class s_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat };

t坐标:enum class t_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat };

r坐标:enum class r_address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat };

address:设置所有纹理坐标的寻址方式

enum class address { clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat };

mip_filter:设置纹理采样的mipMap过滤模式, 如果是none,那么只有一层纹理生效;

enum class mip_filter { none, nearest, linear };


采样器状态
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350