目录

  • 1 HLSL?
  • 2 Builtin Types
  • 3 Vector Values
  • 4 Matrix Values
  • 5 Textures
  • 6 Math
  • 7 Custom Types
  • 8 Variables
  • 9 Functions
  • 10 Control Flow
    • 10.1 if statements
    • 10.2 Loops

原文地址
Shader Tutorials by Ronja。


1 HLSL?

HLSL(High Level Shading Language,高级着色器语言)是Unity用来编写着色器的语言,其用来自定义逻辑并最终决定在屏幕上绘制什么内容。 HLSL是微软设计开发的,供Direct3D API使用的GPU语言。 严格来说,大多数 Unity Shader都是用 CG 编写。Cg是C for Graphics的缩写,Cg与 HLSL 共享大部分语法和功能,并在 2012 年被弃用,因此错误地将Unity Shader中的语言称为HLSL能帮助您在搜索引擎中找到更想要的结果。 理论上Unity 也支持编写GLSL(OpenGL Shading Language)着色器,这是为 OpenGL 设计的语言。因为HLSL有更多示例,并且Unity最终会将Shader将转换为导出平台的对应语言,所以Unity中,我们坚持使用HLSL来编写Shader。
其实上面这段没怎么说清楚为什么咱们用的是HLSL语言来编写Unity Shader。这里来解释一下,编写Shader的语言无非就三种,一是微软平台的HLSL语言,二是OpenGL平台的GLSL语言,三是NVIDA的Cg语言。Cg语言是真正意义上的跨平台着色器语言,即用Cg编写的语言既可以在微软的Direct3D上跑也可以在Open Gl上跑。但是由于Cg和DX9风格的HLSL从写法上说几乎是同一种语言,所以在Unity中HLSL和Cg是等价的。我们一般在CGPROGRAM和ENDCG代码片段中编写。
为了在 Unity 中学习着色器,我们建议您不要从这里开始您的编程之旅。着色器调试起来很麻烦,它们可以做的事情非常有限,而且在许多情况下,您必须朝着与大多数编程上下文略有不同的方向进行处理。 所以我们假设你知道类型、变量、类、方法、循环、if 语句等等的基本编程知识。

2 Builtin Types

内置类型。
fixed、half、float表示浮点数,int表示有符号的整型,uint表示无符号的整型。
在移动端的GPU 上,fixed的范围为-2~2之间的数字,精度为 1/256,half是 16 位浮点数,float是 32 位浮点数。 在PC端GPU 上,所有这些值都是 32 位浮点数,所以为了方便我们会到处使用float,但根据数据的大小选择对应的类型也是一种优化。
整型是只能包含整数值的数字,int 可以包含正值和负值,uint 只能包含正值,使用uint可以带来轻微的性能优势。
此外,还有一个简单的数据类型 bool(布尔值),它保存的值为真或假,因此我们可以将检查结果存储在其中。 如果您将布尔值与其他数字一起使用(例如将它们相加或相乘),它们的行为就像数字 0(如果它为假)或 1(如果它为真)。

3 Vector Values

向量。
我们可以在第2节中的内置类型后面添加一个数字(最大为4)来组成一个多维向量,如fixed4, float2 或 half3。我们向量来表示纹理坐标、颜色和位置。
当我们想访问向量中的某一个值时,如果此向量表示位置,我们依次使用 vector.x、vector.y、vector.z 和 vector.w;当向量表示颜色时 ,我们使用vector.r、vector.g、vector.b 和 vector .a。或者我们也可以这样:vector[2]([]中的2是索引值,是从0开始的,因此4维向量的 4 个值将是 0、1、2 和 3)。
如果我们想从一个向量中获取多个值并将它们放入另一个向量中,我们不必自己构造那个新向量,我们可以使用 Swizzling。 Swizzling 意味着在点之后写入多个向量子值。 如:
vector.xy - 仅获取向量的前 2 个值并将它们放入二维向量中。
vector.zyx - 获取向量的前 3 个值并颠倒它们的顺序。
vector.xxxx - 取向量的第一个值并构建一个全部是该值的 4维向量。

(Swizzling能够提高性能)

4 Matrix Values

矩阵。
像向量在一个方向上扩展基本类型一样,矩阵在两个方向上扩展它们。 它们的语法是将 number x number 附加到标量类型上。 如 float4x4、half3x2 甚至 bool2x4。可以通过像 matrix[3][2] 这样的方括号来访问矩阵的成员,第一个数字表示行,第二个数字表示列。 或者通过像 _m32 这样的访问器。 这钟访问器也可以用于 swizzling,如 matrix._m03_m13_m23 以获取最后一列的前 3 个值并将它们写入 3维 向量。 如果我们使用方括号版本并且只使用一对括号,我们将得到定义该行的向量,如matrix[3]表示第三行。
幸运的是,我们几乎从不需要访问矩阵中的值,所以没必要完全掌握它,如果某天你需要使用到矩阵钟的某个元素,再回过头来看看即可。

5 Textures

纹理。
Hlsl 也有描述纹理的类型。我们后面再讲。

6 Math

算数运算。
除了简单数学中的+ - * / 运算符和 逻辑运算符> < == != ! >= <= && 、|| ,hlsl 还内置了许多数学函数,如 abs、dot、lerp、pow、min、atan2 (支持的函数可以见这里)。
还有一些简写,如 += *= -= 和 /= ,它们修改一个变量,然后再次赋值给它自己,还有var++ 和 var- -,其从给定的变量中加或减 1。
标量类型和向量类型的乘法返回一个向量类型,它们的维数都与数字相乘。 所以 float2(2, 7) * 3 等于 float2(6, 21)。
另外,我们我们使用mul函数来实现矩阵与向量相乘以变换向量。矩阵和向量是具体是怎么计算的,这里不细说。

7 Custom Types

自定义类型。
除了内置类型,我们还可以添加我们自己的类型。 添加你自定义类型的语法是这样的(最后的分号很重要!):

struct typeName{float variable;float2 otherVariable;
};

理论上我们也可以使用 class 关键字,使用继承、成员函数甚至接口,但我从未在任何着色器中遇到过它们,所以我不会在这里解释,等它们出现时再说。 如果您确实想使用这些功能,则语法类似于 C++/C#。
与向量类型一样,我们使用来访问自定义类型的成员变量,例如 instance.variable 或 instance.otherVariable.x。

8 Variables

变量。
hlsl 中的所有数据类型都是值类型。 这意味着一旦我们拥有一个值,我们就可以更改它,而无需通过 new 或类似的方式创建它。
如果我们想创建向量类型,我们可以通过调用函数之类的类型来实现。 在这些情况下,参数类型中的子值数量之和必须与目标类型中的值数量相等。比如我们可以通过传入 4 个float或2 个float 2或一个float、一个float2 和另一个float或者仅一个float4来构建一个新的float4。 如我们可以这样构建我们自定义类型的变量:

typeName instance;
instance.variable = 3.14;
instance.otherVariable = float2(3, 1.4);

我们声明的变量可以在函数内部,在这种情况下,它们只能被该函数内部的其他部分访问,这些部分需晚于变量声明(就像在大多数编程语言中一样);也可以在函数之外,在这种情况下,它们可以被 从着色器中的所有函数访问,无论变量声明在哪儿(但通常在顶部声明它们,在函数上方以轻松找到它们)。

9 Functions

函数。(C#中称为方法)
hlsl 中的大多数函数都在全局范围内。 这意味着它们不属于任何数据类型,我们可以从任何地方调用它们。 它们可以接受多个(或没有)参数并返回一个值。 如果您的函数没有返回值,则必须将返回类型声明为 void。 典型的函数语法如下所示:

returnType functionName(argType arg1, otherArgType arg2){//do some stuff and calculate returnValuereturn returnValue;
}

要调用一个函数,我们只需写下函数名,后跟方括号和后缀中的参数。 如果有多个具有相同名称但参数类型不同的函数,hlsl 将自动找到适合我们调用它的参数的函数。如functionName(arg1, arg2)。

10 Control Flow

流程控制。
对于许多着色器来说,一个接一个执行一个命令就足够了,而不会遗漏或重复任何一个命令。 对于他们中的很多人来说,在两种代码路径之间进行选择也很重要。 众所周知,在着色器中使用控制流是有害的,尤其是在移动 GPU 上会影响您的性能,您应该使用诸如 step 之类的函数。 但是这种方法是完全错误的,因为step这些函数在它们内部其实也是使用了分支,使用它们反而会使你的代码更复杂和阅读。如果使用if能使你的代码更整洁,那么就可以使用它。
(“step不能提高效率”这观点我持保留意见,等考证后再说)

10.1 if statements

if语句。
如下面的例子,如果condition为真,则执行 do thing 块,否则执行 do other thing 块,两个代码块永远不会同时执行。

if(condition){//do thing
} else {//do other thing
}

其中, else是可选的。 条件周围的括号是强制性的。 如果你不使用花括号,该语句只会影响下一行(直到下一个分号,而不是下一个换行符),而不是之后的行。 条件可以是布尔值、数字(在这种情况下 0 为假,任何其他值包括负数为真)或返回两者之一的操作。 如果你有一个与你想要的相反的值(当你想执行一些代码时为假,否则为真),只需在它前面加上一个感叹号,就会翻转:真值变为假,假值变为真。如!flag。

10.2 Loops

循环。
控制哪些代码被执行,哪些不执行的另一种方式是循环。 While 循环是一种更简单的循环。 只要定义它们的条件不再为真,它们就会永久执行。 如果一开始就不是真的,它们根本不会被执行。 它们看起来像这样:

while(condition){//do things
}

重要的是,在 do things 中的某个地方您要讲条件改为true,否则循环while将永远运行,这很糟糕,甚至可能使您的整个编辑器崩溃。
另一种循环是 for 循环,它添加了一些语法糖来迭代和计数,它们是这样定义的。

for(beforeLoopLogic; condition; inLoopLogic){//do things
}

我们偶尔会遍历某个数组,变量索引从 0 到 maxValue-1 ,不那么令人困惑的版本如下:

for(uint index=0;index<maxValue;index++){//do things
}

此代码等效于使用 while 循环的代码:

uint index = 0;
while(index < maxValue){//do thingsindex++;
}

两个循环也支持关键字 break 和 continue。
在您的代码中使用 break 语句会使代码跳转到下一个循环的末尾。 这也将跳出无限的 while 循环。
使用 continue 语句会使循环跳转到循环的下一次迭代的开始。

博主本文链接

[译]Unity3D Shader教程(二)HLSL相关推荐

  1. [译]Unity3D Shader教程(五)Surface Shader Basics

    目录 1 Summary 2 Conversion to simple Surface Shader 3 Standard Lighting Properties 4 Implement a few ...

  2. Unity3d shader 教程一 准备

    Cg编程 游戏引擎中的Cg编程对于OpenGL或Direct3D应用程序,Unity比Cg编程要容易得多.网格和图像(即纹理)的导入由图形用户界面支持; mipmap和法线贴图可以自动计算; 最常见的 ...

  3. Unity3d shader 教程三 RGB立方体

    本教程讨论顶点输出参数和片段输入参数.假设您熟悉"最小的着色器"部分. 在本教程中,我们将编写一个着色器来渲染一个类似于下图所示的RGB多维数据集.表面上每个点的颜色由其坐标确定; ...

  4. 【游戏渲染】【译】Unity3D Shader 新手教程(1/6)

    http://gad.qq.com/article/detail/7175490 该文章来自用户转载 点击阅读原文 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散, ...

  5. 【译】Unity3D Shader 新手教程(1/6)

    刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D Shader编程望而却步.该系列教程的第一篇文章(译者注:即本文,后续还有5篇文章) ...

  6. Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...

  7. 【Unity3D Shader编程】之七 静谧之秋篇 表面着色器的写法 二 —— 自定义光照模式

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  8. Unity3D Shader 新手教程(1/6)

    刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D Shader编程望而却步.该系列教程的第一篇文章(译者注:即本文,后续还有5篇文章) ...

  9. Unity3D Shader基础教程

    此教程将指引你如何建立自己的Shaders,让你的游戏场景看起来更好.Unity配备了强大的阴影和材料的语言工具称为ShaderLab,以程式语言来看,它类似于CgFX和Direct3D的语法,它不只 ...

最新文章

  1. (五)Docker镜像管理2之nginx镜像制作
  2. [Luogu P2014]选课 (树形DP)
  3. SharePoint 服务器端对象模型操作文档库(上传/授权/查看权限)
  4. linux网络编程-----非阻塞connect
  5. Servlet到底是个什么东西???【【博采众长】】
  6. Context 之我见
  7. 二十、UE和UI的区别
  8. Mr.J--Bootstrap使用
  9. 《R语言机器学习:实用案例分析》——1.8节总结
  10. android源码编译出错的原因
  11. http协议、cookie与session介绍
  12. HTTP头域列表与解释 之 request篇
  13. Android10手机无法拉起微信小程序解决方案
  14. JavaWeb开发——注册登录的表单验证
  15. 永恒之蓝(ms17010)漏洞利用
  16. 【人工智能算法】算法基础之K均值聚类算法
  17. Android广告图片轮播,支持无限循环和设置轮播样式、切换时间等
  18. Linux系统的时区时间设置
  19. PHP 在线预览文档
  20. 从零开始速通百度云网盘

热门文章

  1. 宜信技术研发中心暑假实习总结
  2. Tomorrow never knows?(C程序设计进阶第2周)
  3. 生育登记服务制度啥意思?生育服务证和准生证一回事吗?生育那些事
  4. Flutter播放音频
  5. 梦幻仙缘剧情java_梦幻仙缘新春赚红包版
  6. 微信公众号开发者接入
  7. Solar-PuTTY修改背景、字体颜色和字体大小
  8. 计算机串口连接原理,串口通信的原理及USB转串口通信
  9. 聊聊跨端技术的本质与现状
  10. 自动驾驶 11-1: 光检测和测距传感器LIDAR Light Detection and Ranging Sensors