1. 程式人生 > 其它 >第1篇 初始廬山真面目 - unity 3D Shader - Unity 3D ShaderLab開發實踐

第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對應的是光照模型的函式(內建的有StandardStandardSpecularLambertBlinnPhong ),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])諮詢.