1. 程式人生 > >編寫自己的Shader(著色器)

編寫自己的Shader(著色器)

一、Shader 程式的基本結構##

Shader程式的基本結構

首先是一些屬性定義,用來指定這段程式碼將有哪些輸入。接下來是一個或者多個的子著色器,在實際執行中,哪一個子著色器被使用是由執行的平臺所決定的。子著色器是程式碼的主體,每一個子著色器中包含一個或者多個的Pass。在計算著色時,平臺先選擇最優先可以使用的著色器,然後依次執行其中的Pass,然後得到輸出的結果。最後指定一個回滾,用來處理所有Subshader都不能執行的情況(比如目標裝置實在太老,所有Subshader中都有其不支援的特性)。
需要提前說明的是,在實際進行表面著色器的開發時,我們將直接在Subshader這個層次上寫程式碼,系統將把我們的程式碼編譯成若干個合適的Pass。廢話到此為止,下面讓我們真正實際進入Shader的世界吧。

二、進入Shader內部程式碼結構熟悉##

建立Shader內部展示
屬性定義
屬性的對應
SuberShader(子著色器)
SuberShader

三、簡單Shader展示##

Shader "Custom/ShaderTest" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)

        //在輸入貼圖時候,必須要寫一個什麼都不含的{}
        //需要開啟特定選項時可以把其寫在這對花括號內.
        //如果需要同時開啟多個選項,可以使用空白分隔
        _MainTex ("Albedo (RGB)"
, 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 _MainColor("Main Color",Color)=(0,0,0,1) _Testure("Texture",2D)="White"{} } SubShader { //表面著色器可以被若干的標籤(tags)所修飾 //硬體將通過判定這些標籤來決定什麼時候呼叫該著色器 Tags { "RenderType"
="Opaque" }//標籤內部就是告訴系統渲染非透明的物體呼叫我們 //Tags { "RenderType"="Transparent" }//渲染透明物體呼叫 //Tags { "IgnoreProjector"="True" }//不被Projectors影響 //Tags{ "ForceNoShadowCasting"="True" }//不產生陰影 //指定渲染佇列(下面有系統預設的佇列) //Tags{ "Queue"="Geometry" } //Background--最早被呼叫的渲染,用來渲染天空盒或者背景 //Geometry--預設值,用來渲染非透明物體(普通情況下,場景中的絕大多數物體應該是非透明的) //AlphaTest--用來渲染經過Alpha Test的畫素,單獨為AlphaTest設定一個Queue是出於對效率的考慮 //Overlay--用來渲染疊加的效果,是渲染的最後階段(比如鏡頭光暈等特效) //Transparent--以從後往前的順序渲染透明物體 //預設的佇列本質就是定義的整數(有點像列舉值) //Background=1000,Geometry=2000,AlphaTest=2450 //Transparent=3000,最後Overlay=4000 //如何自定義列表 //Tags{ "Queue"="Transparent+200" }//通過呼叫Queue值,確保渲染的先後順序 //Unity的內建Diffuse著色器的設定值,這個數值決定了我們能用什麼樣的Shader //這個數值可以在unity中的質量設定中設定 LOD 200//著色器的設定值 //Decal, Reflective VertexLit = 150 //Diffuse = 200 //Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250 //Bumped, Specular = 300 //Bumped Specular = 400 //Parallax = 500 //Parallax Specular = 600 //Shader字型:也就是將輸入轉變成輸出的程式碼部分 CGPROGRAM//開始CG語言的編寫 // Physically based Standard lighting model, and enable shadows on all light types //surface:申明的是一個表面著色器 //surf:著色器程式碼的方法的名字,下方的程式碼有這個函式 //Standard:標準 //fullforwardshadows:光照模型 #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 //在CG中,sampler2D就是和texture所繫結的一個數據容器介面 //其實就是記憶體儲存的RGB通道,sampler2D:就是GLSL中的2D貼圖的型別 //其他型別:sampler1D,sampler3D,samplerCube // 圖片 sampler2D _MainTex; // 用來獲取MainTex的UV資訊 struct Input { float2 uv_MainTex; // 用來獲取MainTex的UV資訊 vec2 coordinate;//float和vec都可以在之後加入一個2到4的數字,來表示被打包在一起的2到4個同類型數 float4 color; }; half _Glossiness;//half指的是半精度浮點數,精度最低,運算效能相對比高精度浮點數高一些 half _Metallic; // 顏色屬性 fixed4 _Color; // SurfaceOutputStandard 表面著色器輸出一個標準的結構體 //著色器的工作核心,著色器就是給定了輸入,然後給出輸出進行著色的程式碼,第一個引數是Input結果,第二個引數是一個inout的SurfaceOutput結構 void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color // 獲取圖片 * 我們選定的顏色 //fixed4:定點書:整形資料型別,作用就是把所有數進行轉換,得到相應型別的整形表達 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; // 輸出的畫素的顏色 = 影象的顏色(RGB) o.Albedo = c.rgb; // Metallic and smoothness come from slider variables // 輸出的顏色效果(金屬方面) = 設定的金屬值 o.Metallic = _Metallic; // 輸出的光滑粗糙程度 = 設定的光滑粗燥程度 o.Smoothness = _Glossiness; // 輸出的透明通道 = 影象的透明通道 o.Alpha = c.a; } ENDCG//結束CG語言的編寫 } FallBack "Diffuse" }
結構體展示

四、參考##

CG語言

五、CG語音學習資料##