Writing Surface Shaders
Writing shaders that interact with lighting is complex. There are different light types, different shadow options, different rendering paths (forward and deferred rendering), and the shader should somehow handle all that complexity.
编写光照交互的着色器是十分复杂的事情。它们有不同类型的光照,不同的阴影选项,不同的渲染路径(正向渲染和延时渲染),着色器应该以某种合适的方式处理这些的复杂的东西。
Surface Shaders in Unity is a code generation approach that makes it much easier to write lit shaders than using low level vertex/pixel shader programs. Note that there is no custom languages, magic or ninjas involved in Surface Shaders; it just generates all the repetitive code that would have to be written by hand. You still write shader code in Cg / HLSL.
Unity3D的表面着色器编写的办法只有通过编写代码产生,这样就使得编写光照着色器比使用低级顶点/像素着色器编程更简单。请注意编写表面着色器没有任何自定义的语言和捷径。它仅仅是通过手动书写来产生一些重复的代码。
你依然可以用CG/HLSL语言来编写它。
For some examples, take a look at Surface Shader Examples and Surface Shader Custom Lighting Examples.
这有一些例子,你可以看看:表面着色器 和 自定义照明的表面着色器。
How it works 工作原理
You define a "surface function" that takes any UVs or data you need as input, and fills in output structureSurfaceOutput
. SurfaceOutput basically describes properties of the surface (it's albedo color, normal, emission, specularity etc.). You write this code in Cg / HLSL.
你定义一个“surface function”,将UV或数据作为输入参数,并填充SurfaceOutput作为输出结构体。SurfaceOutput描述了基础的表面属性(光照的颜色反射率、法线、自发光、镜面 等)。你可以用Cg/HLSL编写它。
Surface Shader compiler then figures out what inputs are needed, what outputs are filled and so on, and generates actual vertex&pixel shaders, as well as rendering passes to handle forward and deferred rendering.
表面着色器的编译器,指出需要输入什么,在输出中填充什么等等,并产生真实的顶点&像素着色器,并且处理渲染路径为正向渲染或延时渲染。
Standard output structure of surface shaders is this: 标准的表面着色器输出结构体如下:
struct SurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half Gloss; half Alpha; };
Samples 例子
See Surface Shader Examples and Surface Shader Custom Lighting Examples pages.
参考 Surface Shader Examples 和 Surface Shader Custom Lighting Examples 。
Surface Shader compile directives 表面着色器编译指令
Surface shader is placed inside CGPROGRAM..ENDCG
block, just like any other shader. The differences are:
表面着色器必须放在CGPROGRAM..ENDCG块中,就像其他着色器一样。区别在于:
It must be placed inside SubShader block, not inside Pass. Surface shader will compile into multiple passes itself.
它必须放在SubShader块中,不能放在Pass中。表面着色器将在多个通道内编译自己。
- It uses
#pragma surface ...
directive to indicate it's a surface shader. - 它使用#pragma surface 指令来表明自己是表明着色器。
The #pragma surface
directive is: #pragma surface指令使用办法:
#pragma surface surfaceFunction lightModel [optionalparams]
Required parameters: 必须的参数
- surfaceFunction - which Cg function has surface shader code. The function should have the form of
void surf (Input IN, inout SurfaceOutput o)
, where Input is a structure you have defined. Input should contain any texture coordinates and extra automatic variables needed by surface function.表明哪些Cg函数中有表面着色器的代码。这个函数的格式如下:void surf (Input IN,inout SurfaceOutput o), Input是你自定义的结构。Input结构中包含所有纹理坐标和surfaceFunction所需的额外的自动变量。
- lightModel - lighting model to use. Built-in ones are
Lambert
(diffuse) andBlinnPhong
(specular). See Custom Lighting Models page for how to write your own. - 在光照模式中使用。内置的光照模式是Lambert (diffuse)和 BlinnPhong (specular)。请参考:Custom Lighting Models 。
Optional parameters: 可选参数
-
alpha
- Alpha blending mode. Use this for semitransparent shaders. - Alpha混合模式。它可写以被用作半透明的着色处理。
-
alphatest:VariableName
- Alpha testing mode. Use this for transparent-cutout shaders. Cutoff value is in float variable with VariableName. - Alpha测试模式。使用它可以写出透明的剪影效果。剪影的值是用一个float型的变量表示。
-
vertex:VertexFunction
- Custom vertex modification function. See Tree Bark shader for example. - 自定义的顶点修改函数。请参考范例:树皮着色器(Tree Bark shader)。
-
finalcolor:ColorFunction
- Custom final color modification function. See Surface Shader Examples. - 自定义的最终颜色修改函数。 请参考:表面着色器例子Surface Shader Examples
-
exclude_path:prepass
orexclude_path:forward
- Do not generate passes for given rendering path. - prepass(上一通道) 或者 exclude_path:forward - 不要为给定的渲染路径生成通道。
-
addshadow
- Add shadow caster & collector passes. Commonly used with custom vertex modification, so that shadow casting also gets any procedural vertex animation. - 添加阴影投射并且集合通道。通常用于自定义顶点的修改,使阴影也能投射在任何过程的顶点动画上。
-
dualforward
- Use dual lightmaps in forward rendering path. - 在正向渲染路径中使用双重光照贴图
-
fullforwardshadows
- Support all shadow types in Forward rendering path. - 在正向渲染路径中支持所有阴影类型。
-
decal:add
- Additive decal shader (e.g. terrain AddPass). - 添加印花着色器 (例如: 地形 AddPass)。
-
decal:blend
- Semitransparent decal shader. - 混合-半透明的印花着色器(Semitransparent decal shader)。
-
softvegetation
- Makes the surface shader only be rendered when Soft Vegetation is on. - 仅在Soft Vegetation打开时使用表面着色器
-
noambient
- Do not apply any ambient lighting or spherical harmonics lights. - 并不适用于任何环境照明或球面调和照明。
-
novertexlights
- Do not apply any spherical harmonics or per-vertex lights in Forward rendering. - 在正向渲染中,不适用于球面调和照明或逐顶点光照。
-
nolightmap
- Disables lightmap support in this shader (makes a shader smaller). - 在这个着色器上禁用光照贴图。(使着色器变小)
-
nodirlightmap
- Disables directional lightmaps support in this shader (makes a shader smaller). - 在这个着色器上禁用方向光照贴图。 (使着色器变小)。
-
noforwardadd
- Disables Forward rendering additive pass. This makes the shader support one full directional light, with all other lights computed per-vertex/SH. Makes shaders smaller as well. - 禁用正向渲染添加通道。这会使这个着色器支持一个完整的方向光和所有逐顶点/SH计算的光照,使着色器变小。
-
approxview
- Computes normalized view direction per-vertex instead of per-pixel, for shaders that need it. This is faster, but view direction is not entirely correct when camera gets close to surface. - 当着色器有需要的时候,计算每个顶点,而不是每个像素的方向。 这样更快,但是当摄像机接近表面的时候,视图方向不完全正确。
-
halfasview
- Pass half-direction vector into the lighting function instead of view-direction. Half-direction will be computed and normalized per vertex. This is faster, but not entirely correct. - 在光照函数中传递进来的是half-direction向量,而不是视图方向向量。 Half-direction计算且将每个顶点标准化。这样更快,但不完全正确。
Additionally, you can write #pragma debug
inside CGPROGRAM block, and then surface compiler will spit out a lot of comments of the generated code. You can view that using Open Compiled Shader in shader inspector.
另外,你可以在CGPROGRAM 块中使用#pragma debug指令,然后编译器会产生许多注释的代码。你可以在着色器面板中打开这些已经编译好的着色器中查看它们。
Surface Shader input structure 表明着色器输入结构
The input structure Input
generally has any texture coordinates needed by the shader. Texture coordinates must be named "uv
" followed by texture name (or start it with "uv2
" to use second texture coordinate set).
输入结构体Input 包含有着色所需要的纹理坐标。纹理坐标必须在纹理名称后加上"uv"。(或者以"uv2"作为头来命名来使用第二个纹理坐标集)
Additional values that can be put into Input structure:
下列这些附加值 也可放在Input结构中。
-
float3 viewDir
- will contain view direction, for computing Parallax effects, rim lighting etc. - 为了计算视差、边缘光照等效果,Input需要包含视图方向。
-
float4
withCOLOR
semantic - will contain interpolated per-vertex color. - float4的色彩语义:每个顶点颜色的插值
-
float4 screenPos
- will contain screen space position for reflection effects. Used by WetStreet shader in Dark Unity for example. - 屏幕坐标。 为了获得反射效果,需要包含屏幕坐标。比如在Dark Unity例子中所使用的 WetStreet着色器。
-
float3 worldPos
- will contain world space position. - 世界坐标。
-
float3 worldRefl
- will contain world reflection vector if surface shader does not write to o.Normal. See Reflect-Diffuse shader for example. - 世界中的反射向量。如果表面着色不写入o.Normal, 将包含世界反射向量。 请参考这个例子:Reflect-Diffuse 着色器。
-
float3 worldNormal
- will contain world normal vector if surface shader does not write to o.Normal. - 世界中的法线向量。如果表面着色器不写入法线(o.Normal)参数,将包含这个参数。
-
float3 worldRefl; INTERNAL_DATA
- will contain world reflection vector if surface shader writes to o.Normal. To get the reflection vector based on per-pixel normal map, useWorldReflectionVector (IN, o.Normal)
. See Reflect-Bumped shader for example. - 内部数据。如果表面着色写入到o.Normal,将包含世界反射向量 。为了得到基于每个像素的法线贴图的反射向量, 使用WorldReflectionVector的(IN输入, o.Normal)。参照凹凸反射着色器。
-
float3 worldNormal; INTERNAL_DATA
- will contain world normal vector if surface shader writes to o.Normal. To get the normal vector based on per-pixel normal map, useWorldNormalVector (IN, o.Normal)
. - 内部数据。如果表面着色写入到o.Normal, 将包含世界法线向量。为了得到基于每个像素的法线贴图的法线向量,请使用世界法线向量((IN输入, o.Normal)
Further Documentation 更多参考文档
由www.J2meGame.com原创,转载请说明。