从今天起,开始翻译Unity关于shader的官方文档。翻译水平比较一般,目的主要是通过翻译来提升对shader的见解,也让其他人更容易的了解shader。以下开始正文内容:

编写Surface Shaders

  和光交互的shader写起来很复杂,有不同的光照类型、阴影选项、渲染路径(正向渲染和延迟渲染),有时shader需要考虑所有的复杂性。

  Unity中的Surface Shader是一个代码生成器,用它来写光照shader(lit shader)相比于使用低阶的顶点/像素shader(vertex/pixel shader)程序,会更加容易。注意Surface Shader中并没有固定的语言和奇幻的东西(magic or ninjas involved)。它仅仅是生成原本必须由手工重复编写的代码。你也可以用Cg/HLSL来写shader代码。

  这里有一些例子: Surface Shader ExamplesSurface Shader Custom Lighting Examples

它如何工作

  你定义一个“surface 函数”,其输入是你所需要的任意UVs或数据,输出是SurfaceOutput数据结构。SurfaceOutput简单地描述了surface的属性(properties of the surface),如反射率颜色(albedo color)、法线(normal)、散射(emission)、镜面反射(specularity )等。

  Surface Shader编译器会确定需要什么输入,有什么输出等,也会产生实际的顶点&像素shader(vertex&pixel shaders),以及渲染路径来处理正向和延迟渲染。

  surface标准的输出结构如下:

struct SurfaceOutput
2 {
3 fixed3 Albedo; // 漫反射颜色
4 fixed3 Normal; // 切线空间法线,如果赋值的话
5 fixed3 Emission;
6 half Specular; // 高光强度,范围是0-1
7 fixed Gloss; // specular intensity
8 fixed Alpha; // 透明度
9 };

  在Unity 5中,surface shader 也能使用物理光照模型。内建的标准和标准镜面光照模型(见下文)分别使用以下输出结构:

struct SurfaceOutputStandard
{
fixed3 Albedo; // 基础 (漫反射或镜面反射) 颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission;
half Metallic; // 0=非金属, 1=金属
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};
struct SurfaceOutputStandardSpecular
{
fixed3 Albedo; // 漫反射颜色
fixed3 Specular; // 镜面反射颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission;
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};

例子

  参见:Surface Shader ExamplesSurface Shader Custom Lighting Examples and Surface Shader Tessellation

Surface Shader编译指令

  Surface shader放在CGPROGRAM..ENDCG块中,就像其他任何的shader一样。不同处在于:

  • 它必须放在SubShader块中,而不是Pass中。Surface shader将会自动编译进多个pass中。
  • 它使用#pragma surface ...指令来指示它是Surface shader。

  #pragma surface指令如下:

#pragma surface surfaceFunction lightModel [optionalparams]

必须参数

  • surfaceFunction — 拥有surface shader代码的Cg函数。此函数应有这样的格式:void surf (Input IN, inout SurfaceOutput o),其中Input是你定义好的结构,它应该包含任何纹理坐标以及surface函数所需的额外的自动变量。
  • lightModel — 要使用的光照模型。内建的光照模型是基于物理的标准和标准镜面光照模型,以及简单的非物理Lambert(漫反射)和BlinnPhong(镜面)光照模型。参见

Custom Lighting Models

    来学习如何编写。

    • 标准光照模型使用SurfaceOutputStandard输出结构,并匹配Unity中的标准(金属工作流)shader。
    • 标准镜面光照模型使用SurfaceOutputStandardSpecular输出结构,并匹配Unity中的标准(高光设置)shader。
    • Lambert和BinnPhong光照模型是不基于物理的(来自Unity 4.x),但是使用它们的shader在低配电脑上能够渲染地更快。

可选参数

  透明度和alpha测试(Transparency and alpha testing)由alpha和alphatest指令控制。通常透明度有两种类型:传统alpha混合(用于对象淡出)或更逼近物理的“混合预乘”(允许半透明的表面保持合适的镜面反射)。开启半透明度使得产生的surface shader代码包含blending指令:基于给定的变量,开启alpha裁剪将会在生成的像素shader中进行碎片丢弃。

  • alpha 或 alpha:auto —  将会选择fade-transparency (同alpha:fade)作为简单的光照函数,选择premultiplied transparency (同alpha:premul)作为物理光照函数。
  • alpha:fade — 允许传统的透明度渐隐。
  • alpha:premul — 允许预乘alpha透明度。
  • alphatest:VariableName — 允许alpha裁剪透明度。截断值是一个名为VariableName的float类型变量。你还可以使用addshadow指令来生成合适的投影通道。
  • keepalpha — 默认alpha通道中的不透明度为1.0(白色),无论输出结构中的Alpha是多少或者光照函数的返回值是多少。
  • decal:add — 附加的贴花shader(如terrain AddPass)。这对位于其他表面正上方和使用附加混合的对象来说是有意义的。
  • decal:blend — 半透明贴花shader。这对位于其他表面正上方和使用alpha混合的对象来说是有意义的。

  定制修改器函数(Custom modifier functions)能够用来改变或者计算输入的顶点数据,或者改变最终计算出的片段颜色。

  • vertex:VertexFunction — 定制顶点修改器函数. 此函数在生成的顶点shader的开始处被调用,可以修改或计算预顶点数据,参见 Surface Shader Examples
  • finalcolor:ColorFunction — 定制的最终颜色修改器函数。参见Surface Shader Examples

  阴影和镶嵌(Shadows and Tessellation)— 附加指令,用于控制阴影和镶嵌的处理。

  • addshadow — 生成一个投影通道。一般还要使用定制顶点修改器,这样投影也能获取任何程序上的顶点动画。 当shader通过fallback来使用投影时,通常不需要任何特别的阴影处理。
  • fullforwardshadows — 支持 Forward 渲染路径中所有的光照阴影模型。默认shader只支持正向渲染中来自单方向光产生的阴影。如果你需要用点光源或聚光光源来产生阴影,使用该指令。
  • tessellate:TessFunction — 使用DX11 GPU 镶嵌; 该函数计算镶嵌因子。详情参见 Surface Shader Tessellation

  代码生成选项 — 默认生成的surface shader代码会尝试去处理所有可能的光照/阴影/光照贴图场景。尽管如此,在某些情况下你并不需要其中一些,你可以调整生成的代码来跳过它们。这样就能产生更小、加载速度更快的shader。

  • exclude_path:deferredexclude_path:forwardexclude_path:prepass - 对于给定的渲染路径(分别是Deferred ShadingForward 和 Legacy Deferred),不生成相应的通道。
  • noshadow — 在此shader中关闭所有支持阴影功能。
  • noambient — 不应用任何环境光或光照探测(light probes)。
  • novertexlights — 不在正向渲染中应用任何光照探测或预顶点光照。
  • nolightmap — 在此shader中关闭所有支持光照贴图功能。
  • nodynlightmap — 在此shader中关闭支持运行时动态全局光照(runtime dynamic global illumination)功能。
  • nodirlightmap - 在此shader中关闭支持方向光照贴图功能。
  • nofog — 关闭内建的支持所有雾效果功能。
  • nometa — 不产生“meta”通道(该meta用来由光照贴图和动态全局光照提取表面信息)。
  • noforwardadd — 关闭Forward 渲染附加通道。 这使得shader支持单方向完全光照,以及所有其他由每个顶点/SH计算的光照。同时使得shader更小。

  混合选项

  • softvegetation — 当柔性植被开启时,surface shader才会被渲染。
  • interpolateview — 在顶点shader中计算视线方向并进行插值,而不是在像素shader中进行计算。这使得像素shader更快,但会多消耗一个纹理插值器。
  • halfasview — 将half-direction 向量,而不是视线方向向量,传递给光照函数。Half-direction 将被逐顶点计算和单位化。这会更快,但不会完全正确。
  • approxview — 在Unity 5.0中被移除,请用interpolateview 替代。
  • dualforward - 在forward渲染路径中使用dual lightmaps 。

  要了解使用上述不同选项所带来确切的变化,使用Shader Inspector中的“Show Generated Code” 按钮将会有所帮助。

Surface Shader 输入结构

  输入结构 Input 通常有shader所需的任意纹理坐标。纹理坐标必须命名为“uv”+“纹理名称”(或者以“uv2”开头,来使用第二个纹理坐标集)。

输入结构中还能放入一下额外的变量:

  • float3 viewDir — 将会包含视线方向,用来计算视差影响,边缘光照等。
  • float4 with COLOR semantic — 将会包含每个顶点插值后的颜色。
  • float4 screenPos — 将会包含反射或屏幕空间影响下的屏幕空间坐标。
  • float3 worldPos — 将会包含世界空间坐标。
  • float3 worldRefl — 如果surface shader没有赋值o.Normal,将会包含世界反射向量。参见例子:Reflect-Diffuse shader。
  • float3 worldNormal — 如果surface shader没有赋值o.Normal,将会包含世界法向量。
  • float3 worldRefl; INTERNAL_DATA — 如果surface shader没有赋值o.Normal,将会包含世界法向量。为了获得逐像素法线贴图的反射向量,请使用WorldReflectionVector (IN, o.Normal)。参见例子: Reflect-Bumped shader。
  • float3 worldNormal; INTERNAL_DATA — 如果surface shader没有赋值o.Normal,将会包含世界法向量。为了获得逐像素法线贴图的法向量,请使用WorldNormalVector (IN, o.Normal)。

Surface shaders 和 DirectX 11

  目前,surface shader编译管道的部分内容并不能理解 DirectX 11-特定的HLSL 语法, 所以如果你在使用HLSL特性,诸如StructuredBuffers, RWTextures 和其他非DX9 语法,你必须将之包含在只针对DX11的预处理器宏中。详情参见Platform Specific Differences 。

Unity Shader——Writing Surface Shaders(0)的更多相关文章

  1. Unity Shader——Writing Surface Shaders(3)——Surface Shader Lighting Examples

    Surface Shader 光照例子 这里有一些自定义光照模型和Surface Shaders的例子.通常的Surface Shader例子在这里. 由于延迟光照在某些自定义的逐材质光照模型中表现得 ...

  2. Unity Shader——Writing Surface Shaders(2)——Custom Lighting models in Surface Shaders

    Surface Shader中的自定义光照模型 当你在编写 Surface Shaders 时,是在描述一个表面的属性(反射颜色.法线……),而且光的交互过程是由一个光照模型来计算的.内建的光照模型有 ...

  3. Unity Shader——Writing Surface Shaders(1)——Surface Shader Examples

    这里有Surface Shader的一些例子.下面的这些例子关注使用内建的光照模型:关于如何使用自定义光照模型的例子参见Surface Shader Lighting Examples. 简单 我们将 ...

  4. Writing Surface Shaders

    [Writing Surface Shaders] Writing shaders that interact with lighting is complex. There are differen ...

  5. [Unity Shader]Shader前述

    什么是Shader   Shader,也就是着色器,它的工作就是读取你的网格并渲染在屏幕上.Shader可以定义一些属性,你会用它来影响渲染模型时所显示的效果.当存储了这些属性的设置时,就是一个Mat ...

  6. Unity Shader 基础(3) 获取深度纹理

    Unity提供了很多Image Effect效果,包含Global Fog.DOF.Boom.Blur.Edge Detection等等,这些效果里面都会使用到摄像机深度或者根据深度还原世界坐标实现各 ...

  7. Unity shader 官网文档全方位学习(一)

    转载:https://my.oschina.net/u/138823/blog/181131 摘要: 这篇文章主要介绍Surface Shaders基础及Examples详尽解析 What?? Sha ...

  8. 【Unity Shader】(六) ------ 复杂的光照(上)

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题.              [Unity Sha ...

  9. unity shader 编辑器扩展类 ShaderGUI

    这应该unity5才出的新功能了,今天看文档时刚巧看到了,就来尝试了一下. 效果如图: shader 的编辑器扩展分为2种方法: 是通过UnityEditor下的ShaderGUI类来实现的,形式比较 ...

随机推荐

  1. mysql 基础篇1

    1 引入 数据保存到内存: 优点: 1)读写非常快 缺点: 1)程序关闭导致数据丢失 数据保存到文件: 优点: 1)数据可以永久保存 缺点: 1)频繁地IO操作,效率不高! 2)数据管理不方便.例如查 ...

  2. label for

      一般我们在使用radio 时都是结合label来使用的 <label><input type=”radio” name=”radio” value=’0’/>男</l ...

  3. linux注销、关机、重启

    一.Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:[root@laolinux root]#logoutRed Hat Linux release ...

  4. ioS基础篇(十九)——UIResponder简析

    UIResponder类定义了对象相应和控制事件的接口,他是UIApplication.UIView的超类,这类的实例通常被称为应答对象. 一.Responder对象 在iOS系统中,能够响应并处理事 ...

  5. IT的灵魂是流程,流程的灵魂是业务,业务的灵魂是战略

    IT的灵魂是流程,流程的灵魂是业务,业务的灵魂是战略.高效的IT平台不在于IT技术,而在于好的管理模式与流程设计 从以组织为核心转向以流程为核心 流程管理核心是从流程角度出发,关注流程是否增值,籍此建 ...

  6. C++中不同数据类型的互相转换

    1.string --> char *   char * p = (char*)str.c_str(); 2.char * -->string   char *p = "aaa& ...

  7. Python学习笔记-字符串

    Python之使用字符串 1.所有的标准序列操作(索引,分片,乘法,判断成员资格,求长度,取最小值,最大值)对字符串同样适用.但是字符串都是不可变的. 2.字符串格式化使用字符串格式化操作符即%. f ...

  8. mysql linux终端登陆

    mysql -uroot -hlocalhost -psorry 设置远程登录 用户名及密码 GRANT ALL PRIVILEGES ON *.* TO root@"%" IDE ...

  9. CloseableHttpResponse的使用

    *************************** *这篇随手弄出来了,很急躁,有空再改 *************************** 基本逻辑是: 1.定义一个客户端 2.定义一个方法 ...

  10. 苹果IPhone手机由于更新了IOS7 Beta测试版导致“激活出错”后,如何还原电话本和照片方法

    苹果这狗日的,手段果然狠,因为用户提前升级了测试版又没有更新正式版,就突然把手机变砖头,既不让升级正式版,也不让备份手机中的信息,确实有必要这样吗? 我的手机是IPone4s,在看了6月Apple W ...