【Unity Shaders】Shader学习资源和Surface Shader概述
写在前面
什么是Shader
- Surface Shaders —— 也称为表面着色器。这大概是Unity的骄傲。它去除了大部分“麻烦的工作”,可以适用于很多情况下
- Fragment Shaders —— 片段着色器。它允许你做更多的工作,但也更难写,而且它还让我们可以做低层的一些东西,像顶点光照,这对于移动设备和多个通道(passes)所必需的更高级的效果会非常有用。
Shader学习资料
Shader管道
你可以使用Pass中的语句来控制这个Z方向的缓存是否对你的着色器代码有影响,或者你的Shader是否写入该缓冲区内,例如: Zwrite Off表明不会更新你的任何输出像素的Z方向的缓存区。
您可以使用这种技术来在其他对象上打孔 —— 通过写入Z缓冲区,但不输出任何实际的像素颜色,那么使用这个Shader的模型背后的对象将不能被写入(因为Z缓冲区中有距离更近的像素了),这样看起来这个对象就像是被打了洞一样。
下面展示了一个最简单的Surface Shader:
理解Shader代码
Properties
_Name ( "Displayed Name", type ) = default value {options}
- _Name:程序中引用的名字,和我们一般理解的变量名称是一样的。
- Displayed Name:这个字符串将会出现在Unity材质的编辑面板上。
- type:该属性的类型。Unity支持以下几种属性类型:
- Color:表示一个单一的RGBA颜色值;
- 2D: 表示一张大小为2的次方的纹理贴图,可以使用基于模型UV坐标来进行采样;
- Rect:表示一张纹理不是2的次方的纹理贴图;
- Cube:表示一个可用于反射的3D立方体映射贴图,可以进行采样;
- Range(min, max):一个取值范围在min到max之间的浮点值;
- Float: 一个可以为任意值的浮点值;
- Vector:一个4维度的向量。
- default value:该属性的默认值。
- Color:使用浮点值表示的(r, g, b, a),例如(1,1,1,1);
- 2D/Rect/Cube:对于贴图类型的属性,默认值可以是一个空字符串,或者"white", "black", "gray", "bump"这样的字符串;
- Float/Range:在此范围内的值即可;
- Vector:以(x,y,z,w)形式表示的4D向量;
- { options }:只和纹理类型的2D、Rect和Cube相关,它必须至少被指定为{ }。你可以使用空格分隔多个选项,有如下选择:
- TexGen贴图生成模式:该纹理的自动纹理坐标生成模式。可以为ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal。这些直接对应了OpenGL中的texgen modes。注意,如果你编写了一个顶点函数,那么可以忽略TexGen。
//Define a color with a default value of semi-transparent red
_MainColor ("Main Color", Color) = (1,0,0,0.5)
//Define a texture with a default of white
_Texture ("Texture", 2D) = "white" {}
Tags
Shader结构
//Define a float variable
vec2 coordinate;
//Define a color variable
float4 color;
//Multiply out a color
float3 multipliedColor = color.rgb * coordinate.x;
我们可以使用.xyzw和.rgba符号访问存储在这些变量中的值(颜色、位置、法线等)。
从Surface Shader输出信息
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
显然,我们是为SurfaceOutput中的Albedo属性进行了设置。SurfaceOutput是Unity为我们定义的一种结构体,它的定义如下:
struct SurfaceOutput {
half3 Albedo; //The color of the pixel
half3 Normal; //The normal of the pixel
half3 Emission; //The emissive color of the pixel
half Specular; //Specular power of the pixel
half Gloss; //Gloss intensity of the pixel
half Alpha; //Alpha value for the pixel
};
我们只需要填充上述成员变量,Unity在自动生成passes时会自行判断如何使用它们。
struct Input {
float2 uv_MainTex;
};
只需要通过Input结构体,我们就可以告诉系统,为当前正在处理的像素得到在MainTex中对应的纹理坐标。如果不止一张纹理,例如还有一张_OtherTexture,我们只需要添加如下代码:
struct Input {
float2 uv_MainTex;
float2 uv_OtherTexture;
};
如果对于这种纹理,我们需要第二组uv坐标,可以添加如下代码:
struct Input {
float2 uv_MainTex;
float2 uv2_OtherTexture;
};
Input结构体通常包含了所有贴图的uv或uv2坐标。但是,如果我们的Shader比较复杂,并且需要了解像素渲染的其他信息,我也就可以通过将其包括在Input结构体中来要求得到这些变量。
- float3 viewDir:视角方向,用于计算视差效果和边缘照明等;
- 使用COLOR语义的float4:包含了插值后的逐顶点颜色;
- float4 screenPos:屏幕空间中的位置;
- float3 worldPos:世界空间中的位置;
- float3 worldRefl:如果Surface Shader没有改写o.Normal,将包含了环境反射向量;
- float3 worldNormal:如果Surface Shader没有改写o.Normal,将包含了环境法线向量;
- INTERNAL_DATA:当我们需要改写o.Normal时,一些函数,如WorldNormalVector等,需要该变量进行计算;
Sampler2D _MainTex;
当该属性是一张文字,而你需要在Input结构中得到对应的uv坐标时,uv或者uv2后面的名称也必须和属性名相同。
在上图中,_MainTex对应了一张纹理贴图,它对应的变量类型就是sampler2D类型,只要得到了一个uv坐标,我们就可以在贴图上进行采样得到颜色值。
surf函数中仅用了一个函数:
o.Albedo = tex2d( _MainTex, IN.uv_MainTex).rgb;
它使用Input中得到的该像素对应的_MainTex中的uv坐标,在_MainTex进行采样,得到一个float4类型的颜色值(包括了透明通道)。如果我们需要得到透明通道的值,可以这样做:
float4 texColor = tex2d( _MainTex, IN.uv_MainTex );
o.Albedo = texColor.rgb;
o.Alpha = texColor.a;
总结
呼呼呼,本文主要介绍了Unity中Shader的两种主要类型,并对其他的一种类型Surface Shader做了一个初步的概述。希望通过本文,大家可以有一个大概的认识,当然,深入的学习和理解还有很长的一段路要走啊。
【Unity Shaders】Shader学习资源和Surface Shader概述的更多相关文章
- 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 【Unity Shaders】Diffuse Shading——向Surface Shader添加properties
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型
[Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...
- 【Unity Shaders】学习笔记——SurfaceShader(十)镜面反射
[Unity Shaders]学习笔记——SurfaceShader(十)镜面反射 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以. 水 ...
- 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap
[Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...
- 【Unity Shaders】学习笔记——SurfaceShader(七)法线贴图
[Unity Shaders]学习笔记——SurfaceShader(七)法线贴图 转载请注明出处:http://www.cnblogs.com/-867259206/p/5627565.html 写 ...
- 【Unity Shaders】学习笔记——SurfaceShader(六)混合纹理
[Unity Shaders]学习笔记——SurfaceShader(六)混合纹理 转载请注明出处:http://www.cnblogs.com/-867259206/p/5619810.html 写 ...
- 【Unity Shaders】学习笔记——SurfaceShader(五)让纹理动起来
[Unity Shaders]学习笔记——SurfaceShader(五)让纹理动起来 转载请注明出处:http://www.cnblogs.com/-867259206/p/5611222.html ...
- 【Unity Shaders】学习笔记——SurfaceShader(四)用纹理改善漫反射
[Unity Shaders]学习笔记——SurfaceShader(四)用纹理改善漫反射 转载请注明出处:http://www.cnblogs.com/-867259206/p/5603368.ht ...
随机推荐
- [BZOJ]3926 诸神眷顾的幻想乡(ZJOI2015)
听说大佬们都会后缀自动机. 小C看完SAM,想找个裸题练习一下模板.听说这题还是陈老师出的?(羊毛出在羊身上) Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生 ...
- C语言预备作业
一.关于师生关系 第一种:我认为师生关系不是仅仅的餐馆与食客的关系,因为食客可以给餐馆评分,也可以选择是否继续在这里吃,但是学生却不可以选择老师,因为老师是传授知识的,无法由自己来选择.而学生是需要完 ...
- A neural chatbot using sequence to sequence model with attentional decoder. This is a fully functional chatbot.
原项目链接:https://github.com/chiphuyen/stanford-tensorflow-tutorials/tree/master/assignments/chatbot 一个使 ...
- 虚拟机搭建Zookeeper服务器集群完整笔记
虚拟机搭建Zookeeper服务器集群完整笔记 本笔记主要记录自己搭建Zookeeper服务器的全过程,默认已经安装部署好Centos7. 一.虚拟机下Centos无法联网解决方案 1.首先调整虚拟机 ...
- mongodb数据库备份迁移 windows -> linux
mongodb数据库备份迁移 windows -> linux cd 到本机mongodb的安装目录 如: C:\Program Files\MongoDB\Server\3.4\bin 可以发 ...
- java后台通过Servlet给用户发送手机短信验证码,第一次写勿喷,欢迎转载
短信验证码跟自己在Servlet画的验证码不一样,我们不用管短信验证码是怎么产生的,我们只需要关注如何调用短信验证码,在短信验证码里面添加 自己需要的随机数或者其他的内容. 现在直接上流程 第一步找一 ...
- web缓存之--http缓存机制
一.web缓存可以分为数据库缓存.代理服务器缓存.浏览器缓存. 其中浏览器缓存又包含很多内容:http缓存.indexDb.cookie.localStorage等.本片只讨论http缓存相关内容. ...
- 06 Nexus仓储/基础设施 - DevOps之路
06 Nexus仓储/基础设施 - DevOps之路 文章Github地址,欢迎start:https://github.com/li-keli/DevOps-WiKi Nexus仓储官网简介: Th ...
- Vasya the Hipster
One day Vasya the Hipster decided to count how many socks he had. It turned out that he had a red so ...
- Node.js URL
稳定性: 3 - 稳定 这个模块包含分析和解析 URL 的工具.调用 require('url') 来访问模块. 解析 URL 对象有以下内容,依赖于他们是否在 URL 字符串里存在.任何不在 URL ...