第1篇 初始廬山真面目 - unity 3D Shader - Unity 3D ShaderLab開發實踐
第1篇 初始廬山真面目 - unity 3D Shader - Unity 3D ShaderLab開發實踐
2 Unity中Shader的形態
2.1 shader基本結構
Shader "Examples/ShaderSyntax" { CustomEditor = "ExampleCustomEditor" Properties { // Material property declarations go here //[optional: attribute] name("display text in Inspector", type name) = default value } SubShader { // The code that defines the rest of the SubShader goes here //<optional: LOD> //<optional: tags> //<optional: commands> //<One or more Pass definitions> Tags { "ExampleSubShaderTagKey" = "ExampleSubShaderTagValue" } LOD 100 Pass { //<optional: name> //<optional: tags> //<optional: commands> //<optional: shader code> // The code that defines the Pass goes here Name "ExamplePassName" Tags { "ExamplePassTagKey" = "ExamplePassTagValue" } // ShaderLab commands that apply to this Pass go here. // HLSL code goes here. } Pass { // The next pass } } Fallback "ExampleFallbackShader" }
Shader包含:
- 關於自己的資訊;
- 可選的fallback的shader物件;
- 一個或多個subshader
subshader,不同的subshader可以用來針對不同的GPU設定,不同的硬體,不同的渲染管線,和不同的執行時設定,一個subshader,為了獲取想要的渲染效果定製的一個完整的渲染過程,包含:
- 基本資訊,包括硬體,渲染管線,執行時資訊;
- 關於subshader的key-value pair資訊;
- 一個或多個passes;
passes,一個pass指的是一次操作得到一次繪製結果的過程,就好比執行了一次頂點著色器,片段著色器,並輸出了一張繪製結果,SubShader下的Pass會按照從上往下的順序依次渲染。pass中包含:
- 關於pass的key-value tag資訊;
- shader programs前需要設定的render state;
- shader programs;
2.3 Unity中shader的2中形態
2.3.1 vertex+fragment shader
需要實現頂點和片段著色器,可以定製平臺編譯目標相關的引數。
2.3.2 Surface Shader
編寫與光照互動的著色器很複雜。有不同的燈光型別,不同的陰影選項,不同的渲染路徑 (前向和延遲渲染),著色器應該以某種方式處理所有這些複雜性。
SurfaceOutput的結果如下:
struct SurfaceOutput { half3 Albedo; //顏色紋理 half3 Normal; //法線,tangent space空間 half3 Emission; //自發光,不受照明的影響 half Specular; //高光指數,0..1範圍 half Gloss; //光澤度 half Alpha; //Alpha通道 };
此處需要注意的是SurfaceShader中,支援的自定的函式常見的有:
#pragma surface surfaceFunction lightModel vertex:vert finalcolor:colorFunc
surfaceFunction對應的是surface函式,lightModel對應的是光照模型的函式(內建的有Standard ,StandardSpecular ,Lambert,BlinnPhong ),vert是自定義的頂點函式,colorFunc是自定義的最終顏色修改函式。
具體例項可以參見:Unity - Manual: Surface Shader examples (unity3d.com)
參見:Unity Shader - Writing Surface Shaders 編寫表面著色器_Jave.Lin 的學習筆記-CSDN部落格
2.4 屬性和uniform變數
// in property
_MyColor ("Some Color", Color) = (1,1,1,1)
_MyVector ("Some Vector", Vector) = (0,0,0,0)
_MyFloat ("My float", Float) = 0.5
_MyTexture ("Texture", 2D) = "white" {}
_MyCubemap ("Cubemap", CUBE) = "" {}
// in hlsl
fixed4 _MyColor; // low precision type is usually enough for colors
float4 _MyVector;
float _MyFloat;
sampler2D _MyTexture;
samplerCUBE _MyCubemap;
Properties支援的型別
Type | Example syntax | Comment |
---|---|---|
Integer | _ExampleName ("Integer display name", Integer) = 1 |
This type is backed by a real integer (unlike the legacy Int type described below, which is backed by a float). Use this instead of Int when you want to use an integer. |
Int (legacy) | _ExampleName ("Int display name", Int) = 1 |
Note: This legacy type is backed by a float, rather than an integer. It is supported for backwards compatibility reasons only. Use the Integer type instead. |
Float | _ExampleName ("Float display name", Float) = 0.5 _ExampleName ("Float with range", Range(0.0, 1.0)) = 0.5 |
The maximum and minimum values for the range slider are inclusive. |
Texture2D | _ExampleName ("Texture2D display name", 2D) = "" {} _ExampleName ("Texture2D display name", 2D) = "red" {} |
Put the following values in the default value string to use one of Unity’s built-in textures: “white” (RGBA: 1,1,1,1), “black” (RGBA: 0,0,0,1), “gray” (RGBA: 0.5,0.5,0.5,1), “bump” (RGBA: 0.5,0.5,1,0.5) or “red” (RGBA: 1,0,0,1). If you leave the string empty or enter an invalid value, it defaults to “gray”. Note: these default textures are not visible in the Inspector. |
Texture2DArray | _ExampleName ("Texture2DArray display name", 2DArray) = "" {} |
For more information, see Texture arrays. |
Texture3D | _ExampleName ("Texture3D", 3D) = "" {} |
The default value is a “gray” (RGBA: 0.5,0.5,0.5,1) texture. |
Cubemap | _ExampleName ("Cubemap", Cube) = "" {} |
The default value is a “gray” (RGBA: 0.5,0.5,0.5,1) texture. |
CubemapArray | _ExampleName ("CubemapArray", CubeArray) = "" {} |
See Cubemap arrays. |
Color | _ExampleName("Example color", Color) = (.25, .5, .5, 1) |
This maps to a float4 in your shader code. The Material Inspector displays a color picker. If you would rather edit the values as four individual floats, use the Vector type. |
Vector | _ExampleName ("Example vector", Vector) = (.25, .5, .5, 1) |
This maps to a float4 in your shader code. The Material Inspector displays four individual float fields. If you would rather edit the values using a color picker, use the Color type. |
通過指令碼控制屬性:
矩陣不能定義到Property中,只能夠通過指令碼的方式進行設值。
3 Shader中用到的各種空間的概念
用到的空間包括:模型空間、世界座標空間、視空間(相機空間)、視錐體、裁剪空間。
世界空間到模型空間的變換矩陣:transform.worldToLocalMatrix, shader中是_World2Object;
模型空間到世界空間的變換矩陣:transform.localToWorldMatrix, shader中是_Object2World;
世界空間到相機空間的變換為:camera.worldToCameraMatrix,Shader中對應的是UNITY_MATRIX_MV
,可以把向量從模型空間變換到相機空間;
視錐體,如下:
裁剪空間,就是將視錐體變換成為一個長方體。
camera.projectionMatrix, shader中對應的是UNITY_MATRIX_MVP,直接把物體上的點投影到螢幕上。
4 基本光照模型
LightingLambert計算漫反射光,Editor/Data/CGIncludes/Lighting.cginc
乘上了atten * 2是為了更容易達到過曝;
BlinnPhong計算:
具體參見:games101 - 2 - Shading - grassofsky - 部落格園 (cnblogs.com)
其他
Unity - Manual: Built-in shader helper functions (unity3d.com)
Unity Shader內建appdata結構 - 老嶽部落格 - 部落格園 (cnblogs.com)
Unity3d之Shader篇_風宇衝_新浪部落格 (sina.com.cn)
版權說明作者: grassofsky
出處: http://www.cnblogs.com/grass-and-moon
本文版權歸作者,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出, 原文連結 如有問題, 可郵件([email protected])諮詢.