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) and BlinnPhong (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 or exclude_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 with COLOR 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, use WorldReflectionVector (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, use WorldNormalVector (IN, o.Normal).
內部數據。如果表面着色寫入到o.Normal, 將包含世界法線向量。為了得到基於每個像素的法線貼圖的法線向量,請使用世界法線向量((IN輸入, o.Normal)
Further Documentation 更多參考文檔
Surface Shader Examples
Custom Lighting models in Surface Shaders
Surface Shader Lighting Examples
由www.J2meGame.com原創,轉載請說明。