标题: [Unity 组件参考手册]iOS:着色器参考之编写表面着色器 [打印本页] 作者: . 时间: 2013-2-21 17:09 标题: [Unity 组件参考手册]iOS:着色器参考之编写表面着色器 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.表面着色器(Surface Shaders)在Unity中是一个代码生成的方法,使得它更容易用低级的顶点(vertex)/像素(pixel)着色程序编写被照亮的着色器。注意,在表面着色器(Surface Shaders)中没有定制好的语言,魔法或忍者参与。它只是反复的产生代码,这些代码你必须自己动手写。所以你仍然要用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 s***cture SurfaceOutput. 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.通过表面着色器(Surface Shader)编译它,然后计算出需要填充输入什么,输出什么等等这些东西,并产生真实的顶点(vertex)&像素(pixel)着色器,以及把渲染路径传递到正向或延时渲染路径。Standard output s***cture of surface shaders is this:表面着色器(Surface Shader)的标准输出结构是这样的:s***ct 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 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块里面。表面着色器( Surface shader)将在多重通道(multiple passes)内编译自己。
It uses #pragma surface ... directive to indicate it's a surface shader.
它使用的 #pragma surface...指令,以声明它是一个表面着色器(surface shader)。 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 s***cture you have defined. Input should contain any texture coordinates and extra automatic variables needed by surface function.
surfaceFunction - 表示Cg函数中有表面着色器(surface shader)代码。这个函数的格式应该是这样:void surf (Input IN,inout SurfaceOutput o), Input是你自己定义的结构。Input结构中应该包含所有纹理坐标(texture coordinates)和和表面函数(surfaceFunction)所需要的额外的必需变量。
lightModel - lighting model to use. Built-in ones are Lambert (diffuse) and BlinnPhong (specular). See Custom Lighting Models page for how to write your own.
lightModel -在光照模式中使用。内置的是Lambert (diffuse)和 BlinnPhong (specular)。如果想编写自己的光照模式,请参考:自定义光照模式。Optional parameters:可选参数: alpha - Alpha blending mode. Use this for semitransparent shaders.
alpha -透明( Alpha)混合模式。使用它可以写出半透明的着色器。
alphatest:VariableName - Alpha testing mode. Use this for transparent-cutout shaders. Cutoff value is in float variable with VariableName.
alphatest:VariableName -透明( Alpha)测试模式。使用它可以写出 镂空效果的着色器。镂空大小的变量(VariableName)是一个float型的变量。
vertex:VertexFunction - Custom vertex modification function. See Tree Bark shader for example.
vertex:VertexFunction - 自定义的顶点函数(vertex function)。请参考范例:树皮着色器(Tree Bark shader)。
finalcolor:ColorFunction - Custom final color modification function. See Surface Shader Examples.
finalcolor:ColorFunction - 自定义的最终颜色函数(final color function)。 请参考范例:表面着色器例子(Surface Shader Examples)。
exclude_path:prepass or exclude_path:forward - Do not generate passes for given rendering path.
exclude_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.
addshadow - 添加阴影投射 & 收集通道(collector passes)。通常用自定义顶点修改,使阴影也能投射在任何程序的顶点动画上。
dualforward - Use dual lightmaps in forward rendering path.
dualforward - 在正向(forward)渲染路径中使用 双重光照贴图(dual lightmaps)。
fullforwardshadows - Support all shadow types in Forward rendering path.
fullforwardshadows - 在正向(forward)渲染路径中支持所有阴影类型。
decal:add - Additive decal shader (e.g. terrain AddPass).
decal:add - 添加贴花着色器(decal shader) (例如: terrain AddPass)。
decal:blend - Semitransparent decal shader.
decal:blend - 混合半透明的贴花着色器(Semitransparent decal shader)。
softvegetation - Makes the surface shader only be rendered when Soft Vegetation is on.
softvegetation - 使表面着色器(surface shader)仅能在Soft Vegetation打开时渲染。
noambient - Do not apply any ambient lighting or spherical harmonics lights.
noambient - 不适用于任何环境光照(ambient lighting)或者球面调和光照(spherical harmonics lights)。
novertexlights - Do not apply any spherical harmonics or per-vertex lights in Forward rendering.
novertexlights - 在正向渲染(Forward rendering)中不适用于球面调和光照(spherical harmonics lights)或者每个顶点光照(per-vertex lights)。
nolightmap - Disables lightmap support in this shader (makes a shader smaller).
nolightmap - 在这个着色器上禁用光照贴图(lightmap)。(适合写一些小着色器)
nodirlightmap - Disables directional lightmaps support in this shader (makes a shader smaller).
nodirlightmap - 在这个着色器上禁用方向光照贴图(directional lightmaps)。 (适合写一些小着色器)。
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.
noforwardadd - 禁用正向渲染添加通道(Forward rendering additive pass)。 这会使这个着色器支持一个完整的方向光和所有光照的per-vertex/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.
approxview - 着色器需要计算标准视图的每个顶点(per-vertex)方向而不是每个像索(per-pixel)方向。 这样更快,但是视图方向不完全是当前摄像机(camera) 所接近的表面。
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.
halfasview - 在光照函数(lighting function)中传递进来的是half-direction向量,而不是视图方向(view-direction)向量。 Half-direction会计算且会把每个顶点(per vertex)标准化。这样做会很快,但不完全准确。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.此外,你可以在 CGPROGRA内编写 #pragma debug,然后表面编译器(surface compiler)会进行解释生成代码。你可以在着色器面板(inspector)里查看打开编译好的着色器。
Surface Shader input s***cture 表面着色器输入结构The input s***cture 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 这个输入结构通常拥有着色器需要的所有纹理坐标(texture coordinates)。纹理坐标(Texture coordinates)必须被命名为“uv”后接纹理(texture)名字。(或者uv2开始,使用第二纹理坐标集)Additional values that can be put into Input s***cture:可以在输入结构中附加一些值: float3 viewDir - will contain view direction, for computing Parallax effects, rim lighting etc.
float3 viewDir - 视图方向( view direction)值。为了计算视差效果(Parallax effects),边缘光照(rim lighting)等,需要包含视图方向( view direction)值。
float4 with COLOR semantic - will contain interpolated per-vertex color.
float4 with COLOR semantic -每个顶点(per-vertex)颜色的插值。
float4 screenPos - will contain screen space position for reflection effects. Used by WetStreet shader in Dark Unity for example.
float4 screenPos - 屏幕空间中的位置。 为了反射效果,需要包含屏幕空间中的位置信息。比如在Dark Unity中所使用的 WetStreet着色器。
float3 worldPos - will contain world space position.
float3 worldPos - 世界空间中的位置。
float3 worldRefl - will contain world reflection vector if surface shader does not write to o.Normal. See Reflect-Diffuse shader for example.
float3 worldRefl - 世界空间中的反射向量。如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数。 请参考这个例子:Reflect-Diffuse 着色器。
float3 worldNormal - will contain world normal vector if surface shader does not write to o.Normal.
float3 worldNormal - 世界空间中的法线向量(normal vector)。如果表面着色器(surface shader)不写入法线(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, use WorldReflectionVector (IN, o.Normal). See Reflect-Bumped shader for example.
float3 worldRefl; INTERNAL_DATA - 世界空间中的反射向量。如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数。为了获得基于每个顶点法线贴图( per-pixel normal map)的反射向量(reflection vector)需要使用世界反射向量(WorldReflectionVector (IN, o.Normal))。请参考这个例子: Reflect-Bumped着色器。
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, use WorldNormalVector (IN, o.Normal).
float3 worldNormal; INTERNAL_DATA -世界空间中的法线向量(normal vector)。如果表面着色器(surface shader)不写入法线(o.Normal)参数,将包含这个参数。为了获得基于每个顶点法线贴图( per-pixel normal map)的法线向量(normal vector)需要使用世界法线向量(WorldNormalVector (IN, o.Normal))。 Further Documentation 更多的资料请参考下面的例子 表面着色器范例(Surface Shader Examples)
在表面着色器中自定义光照模式Custom Lighting models in Surface Shaders
表面着色器光照范例Surface Shader Lighting Examples 【来源:互联网】
更多精彩教程,尽在web3D纳金网http://www.narkii.com/college/