From today onwards, we start translating Unity's official documents on shader. Translation level is more general, the purpose is mainly through translation to enhance the view of shader, but also make it easier for others to understand shader. The following starts the body content:
Write
Surface Shaders
Shader that interact with light are very complex to write, with different illumination types, shadow options, render paths (forward rendering and deferred rendering), and sometimes shader need to consider all the complexities.
Surface shader in unity is a code generator, and it's easier to write light shader (lit shader) than using a low-order vertex/Pixel shader (Vertex/pixel shader) program. Note that there is no fixed language and magical stuff in surface shader (magic or ninjas involved). It is simply generating code that would otherwise have to be written repeatedly by hand. You can also use CG/HLSL to write shader code.
Here are some examples: surface Shader Examples, surface Shader Custom Lighting Examples.
How it works
You define a "surface function" whose input is any uvs or data you need, and the output is the SURFACEOUTPUT data structure. Surfaceoutput simply describes the properties of surface, suchas the reflectivity color (albedo color), normal (normal), scattering (emission), Specular reflection (specularity) and so on.
The Surface shader compiler will determine what inputs are required, what outputs, and so on, will also produce the actual vertex & pixel shader (Vertex&pixel shaders), as well as the render path to handle forward and deferred rendering.
The output structure of surface standard is as follows:
struct SurfaceOutput2 {3 fixed3 Albedo; Diffuse color 4 fixed3 Normal; Tangent space Normal, if assigned value 5 fixed3 emission;6 half specular; High light intensity, range is 0-17 fixed Gloss; Specular intensity8 fixed Alpha; Transparency 9};
In Unity 5, surface shader can also use the physical lighting model. The built-in standard and standard specular illumination models (see below) use the following output structure, respectively:
struct surfaceoutputstandard{ fixed3 Albedo; Base (diffuse or specular) color fixed3 Normal; Tangent space Normal, if assigned value HALF3 emission; Half metallic; 0= nonmetal, 1= metal half smoothness; 0= Coarse, 1 = smooth half occlusion; Occlusion (default 1) fixed Alpha; Transparency };struct surfaceoutputstandardspecular{ fixed3 Albedo; Diffuse reflectance color fixed3 specular; Specular reflection color fixed3 Normal; Tangent space Normal, if assigned value HALF3 emission; half smoothness; 0= Coarse, 1 = smooth half occlusion; Occlusion (default 1) fixed Alpha; Transparency};
Example
See also: Surface Shader Examples, surface Shader Custom Lighting Examples and surface Shader tessellation.
Surface Shader Compilation Instructions
Surface shader on Cgprogram. ENDCG block, just like any other shader. Different places are:
- It must be placed in the Subshader block, not in the pass. Surface shader will be automatically compiled into multiple passes.
- It uses #pragma surface ... directive to indicate that it is surface shader.
#pragma surface instructions are as follows:
#pragma surface surfacefunction Lightmodel [Optionalparams]
Required Parameters
- surfacefunction-has a CG function that has surface shader code. This function should have this format: void surf (input in, InOut surfaceoutput o), where input is the structure you define, it should contain any texture coordinates and additional automatic variables required by the surface function.
lightmodel-the lighting model to use. The built-in lighting model is a physical-based standard and standard specular illumination model, as well as simple non-physical Lambert (diffuse reflection) and blinnphong (specular) illumination models. See
Custom Lighting Models
to learn how to write.
- The standard lighting model uses the Surfaceoutputstandard output structure and matches the standard (metal workflow) shader in unity.
- The standard specular illumination model uses the Surfaceoutputstandardspecular output structure and matches the standard (highlight setting) shader in unity.
- The Lambert and Binnphong lighting models are not physically based (from Unity 4.x), but the shader that use them can render faster on low-provisioned computers.
Optional parameters
The transparency and alpha tests (Transparency and alpha testing) are controlled by the Alpha and alphatest directives. There are usually two types of transparency: traditional alpha blending (for object fade out) or more approximation to the physical "blend pre-multiplication" (which allows translucent surfaces to maintain appropriate specular reflections). Turn on semi-transparent so that the resulting surface shader code contains the blending directive: turning on Alpha clipping based on a given variable will fragment in the resulting pixel shader.
alpha
Oralpha:auto — 将会选择fade-transparency (同alpha:fade
)作为简单的光照函数,选择premultiplied transparency (同alpha:premul
)作为物理光照函数。
alpha:fade
-Allows traditional transparency to fade.
alpha:premul
-Allows pre-multiplication of alpha transparency.
alphatest:VariableName
-Allows alpha to crop transparency. The truncation value is a float type variable named variablename. You can also use the Addshadow command to generate the appropriate projection channel.
keepalpha
-The opacity in the default alpha channel is 1.0 (white), regardless of how much alpha is in the output structure or what the light function returns.
decal:add
-Additional decals shader (such as terrain addpass). This is meaningful for objects that are positioned just above other surfaces and that use additional blending.
decal:blend
-Translucent applique shader. This is meaningful for objects that are positioned just above other surfaces and that use alpha blending.
The custom modifier function (custom modifier functions) can be used to change or calculate the input vertex data, or to change the final computed fragment color.
vertex:VertexFunction
-Custom vertex modifier functions. This function is called at the beginning of the generated vertex Shader, and you can modify or calculate the pre-vertex data, see Surface Shader Examples.
finalcolor:ColorFunction
-Customize the final color modifier function. See Surface Shader Examples.
Shadows and Mosaics (Shadows and tessellation)-Additional directives to control the processing of shadows and mosaics.
addshadow
-Generates a projection channel. A custom vertex modifier is also commonly used, so that the projection can also get vertex animations on any program. When shader uses projections through fallback, it usually does not require any special shading.
fullforwardshadows
-Supports all light shadow models in the Forward render path. The default shader only supports shadows from single-directional light in forward rendering. If you need to use a point light or spot light to create a shadow, the directive is used.
tessellate:TessFunction
-Use DX11 GPU inlay; The function calculates the mosaic factor. See Surface Shader tessellation for details.
code Generation options -the surface shader code generated by default will attempt to process all possible light/shadow/light map scenes. However, in some cases you don't need some of them, you can tweak the generated code to skip them. This results in a smaller, faster-loading shader.
exclude_path:deferred
, exclude_path:forward
exclude_path:prepass
-for a given render path (Deferred shading, Forward and Legacy Deferred, respectively), the corresponding channel is not generated.
noshadow
-Turn off all shadow support features in this shader.
noambient
-No ambient light or light probes is applied.
novertexlights
-Do not apply any light probing or pre-vertex lighting in forward rendering.
nolightmap
-Turn off all support lighting mapping features in this shader.
nodynlightmap
-Turn off support for runtime dynamic global Illumination (Runtime Dynamics global illumination) feature in this shader.
nodirlightmap
-Turn off the support directional lighting mapping feature in this shader.
nofog
-Off built-in support for all fog effects features.
nometa
-Does not produce a "meta" channel (this meta is used to extract surface information from light maps and dynamic global illumination).
noforwardadd
-Turn off forward render additional channels. This allows shader to support single-sided full illumination, and all other lighting computed by each vertex/sh. It also makes shader smaller.
Blending options
softvegetation
-Surface shader will not be rendered until the soft vegetation is turned on.
interpolateview
-Calculates the line of sight direction in the vertex shader and interpolates it instead of the pixel shader. This makes the pixel shader faster, but consumes one more texture interpolator.
halfasview
-Pass the half-direction vector, not the line of sight direction vector, to the light function. Half-direction will be calculated and unit by vertex. This will be faster, but not entirely true.
approxview
-Removed in Unity 5.0, please use an interpolateview
alternative.
dualforward
-Use dual lightmaps in the forward render path.
To understand the exact changes that are made using the different options above, using the "Show Generated Code" button in Shader inspector will help.
Surface Shader Input Structure
The input structure Input
usually has any texture coordinates required by the shader. The texture coordinates must be named "UV" + "texture name" (or start with "uv2" to use the second set of texture coordinates).
Additional variables can also be placed in the input structure:
float3 viewDir
-will include line of sight direction to calculate parallax effects, edge illumination, etc.
float4
The COLOR
with semantic-will contain the color after each vertex interpolation.
float4 screenPos
-will contain screen space coordinates under reflection or screen space influence.
float3 worldPos
-The world space coordinates will be included.
float3 worldRefl
-If surface shader is not assigned a value O. Normal, will contain the world reflection vector. See example: Reflect-diffuse shader.
float3 worldNormal
-If surface shader is not assigned a value O. Normal, will contain the world law vector.
float3 worldRefl; INTERNAL_DATA
-If surface shader is not assigned a value O. Normal, will contain the world law vector. In order to get the reflection vectors for pixel-wise normal maps, use WorldReflectionVector (IN, o.Normal)。参见例子:
reflect-bumped shader.
float3 worldNormal; INTERNAL_DATA
-If surface shader is not assigned a value O. Normal, will contain the world law vector. In order to get the normal vector of pixel-wise normals map, use theWorldNormalVector (IN, o.Normal)。
Surface Shaders and DirectX 11
Currently, some of the content in the surface Shader compilation pipeline does not understand DirectX 11-specific HLSL syntax, so if you are using HLSL attributes such as Structuredbuffers, Rwtextures, and other non-DX9 syntax, You must include it in the preprocessor macro for DX11 only. See platform specific Differences for details.
Unity shader--writing Surface Shaders (0)