亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Unity中的Shader

 更新時間:2021年06月26日 14:34:15   作者:我聽到你了  
Shader,中文名為著色器,對很多開發(fā)者來說它是一個神秘的存在。Shader其實就是專門用來渲染圖形的一種技術(shù),通過shader,我們可以自定義顯卡渲染畫面的算法,使畫面達到我們想要的效果

一、Shader基礎(chǔ)知識

1.1、什么是Shader

在講什么是Shader之前我們先看看下面兩段代碼 

這里寫圖片描述

這兩段代碼實現(xiàn)的功能都是提取 2D 圖像上每個像素點的顏色值,第一段代碼是用c++寫的,在cup上面運行,它需要循環(huán)遍歷每個像素點,第二段代碼是CG代碼,在GPU上面運行,它只需要一行代碼就能實現(xiàn)同樣的功能。GPU是專門用來進行圖形處理的,而Shader,就是GPU執(zhí)行的一段針對3D對象進行操作的程序。

維基百科上對shader的解釋是這樣

Shader(著色器)應(yīng)用于計算機圖形學(xué)領(lǐng)域,指一組供計算機圖形資源在執(zhí)行渲染任務(wù)時使用的指令,用于計算圖像的顏色或明暗。但近來,它也能用于處理一些特殊效果,或者視頻后處理。通俗地說,著色器告訴電腦如何用特有的一種方法去繪制物體。

程序員將著色器應(yīng)用于圖形處理器(GPU)的可編程流水線,來實現(xiàn)三維應(yīng)用程序。這樣的圖形處理器有別于傳統(tǒng)的固定流水線處理器,為GPU編程帶來更高的靈活性和適應(yīng)性。以前固有的流水線只能進行一些幾何變換和像素灰度計算。現(xiàn)在可編程流水線還能處理所有像素、頂點、紋理的位置、色調(diào)、飽和度、明度、對比度并實時地繪制圖像。著色器還能產(chǎn)生如模糊、高光、有體積光源、失焦、卡通渲染、色調(diào)分離、畸變、凹凸貼圖、邊緣檢測、運動檢測等效果。

1.2、OpenGL的渲染流程

知道了什么是shader,我們再來了解一下shader的種類,首先我先介紹一下OpenGL的渲染流程

這里寫圖片描述

上圖便是OpenGL的渲染流程,將這個流程簡化之后是這樣的 

頂點變換 → 圖元裝配和光柵化 → 片元紋理映射和著色 → 寫入幀緩存

在頂點變換和片元著色這兩步時,我們就可以對其編程,進行各種操作,其他的部分我們是沒法進行編程的。我們的shader就是作用于頂點變換和片元著色這兩個部分的。

1.3、shader的種類

知道了shader起作用的地點,我們現(xiàn)在可以了解一下shader的種類了。

shader按管線分類一般分為固定渲染管線與可編程渲染管線。固定渲染管線就是功能固定的管線,比如物體表面光的折射,反射的算法是固定無法修改的,我們只能對這些功能進行配置,比如開啟或關(guān)閉反射效果,霧化效果等。因為這種管線功能固定,無法在程序上對物體細(xì)節(jié)的表現(xiàn)給予更多更自由的控制,無法達到更多我們想要的畫面效果。所以現(xiàn)在的顯卡都是可編程渲染管線,也就是曾經(jīng)那些我們固定無法修改的部門現(xiàn)在可以編程去修改,自由度高了之后,我們也就能實現(xiàn)更多自己想要的特效了。

1.4、shader的開發(fā)語言

知道了shader的種類,我在來說說shader的開發(fā)語言

HLSL: 主要用于Direct3D。平臺:windows。

GLSL: 主要用于OpenGL。 平臺:移動平臺(iOS,安卓),mac(only use when you target Mac OS X or OpenGL ES 2.0)

CG:與DirectX 9.0以上以及OpenGL 完全兼容。運行時或事先編譯成GPU匯編代碼。CG比HLSL、GLSL支持更多的平臺,Unity Shader采用CG/HLSL作為開發(fā)語言。

二、Unity中Shader知識介紹

2.1、shader在GPU的渲染流程

這里寫圖片描述

進入GPU運算首先進行的是Vertex Processor頂點處理器,這個部分就需要我們使用Vertex Shader頂點著色器,頂點著色器運算的結(jié)果會交給Pixel Processor像素處理器,也就是片段處理器,在這個部分我需要為像素處理編寫Pixel Shader像素著色器程序,這部分計算完后就輸出了最終我們可以用于在屏幕上的顏色信息,我們把它叫做Frame Buffer幀緩沖。幀緩沖存儲的是計算機依次顯示所要的數(shù)據(jù)。

2.2、Unity中shader的類型

①Fixed function shader :屬于固定渲染管線 Shader, 基本用于高級Shader在老顯卡無法顯示時的回滾。使用的是ShaderLab語言,語法與微軟的FX files 或者NVIDIA的 CgFX類似。

②Vertex and Fragment Shader:最強大的Shader類型,屬于可編程渲染管線. 使用的是CG/HLSL語法。

③Surface Shader:Unity3d推崇的Shader類型,使用Unity預(yù)制的光照模型來進行光照運算。使用的也是CG/HLSL語法。

我們先了解一下這三種shader的異同點。

相同點: 

①都必須從唯一一個根Shader開始 
②Properties參數(shù)部分,作用及語法完全相同 
③具體功能都在SubShader里(Subshader會自上而下運行第一個硬件能支持的) 
④SubShader都可以打標(biāo)簽 
⑤都可以回滾 
⑥都可以處理基本的功能,例如光照漫反射(Diffuse)以及鏡面反射(Specular)。但是Vertex and Fragment和Surface都能實現(xiàn)Fixed function實現(xiàn)不了的高級功能,例如基于uv計算的效果等等。

不同點 

①Fixed function shader以及Vertex and Fragment Shader在subshader下面還有pass{}結(jié)構(gòu),但是Surface Shader,已經(jīng)將具體內(nèi)容打包在光照模型了,不能加pass{} 
②Fixed function shader每句代碼之后沒有分號“;”, 但是V&F shader以及Surface shader每句代碼之后都必須加分號“;” 
③核心結(jié)構(gòu)不同 

Fixed function shader的SunShader中的結(jié)構(gòu)為

Material{} 
……
SetTexture[_MainTex]{
    ……
}

Vertex and Fragment Shader的核心結(jié)構(gòu)為

CGPROGRAM
#pragma vertex vert
#pragma fragment frag   
……       
#include "UnityCG.cginc"
ENDCG

Surface Shader的核心結(jié)構(gòu)是

CGPROGRAM
#pragma surface surf Lambert
……
ENDCG

可以看到這三種shader的Subshader內(nèi)的編碼實現(xiàn)是不一樣的,這三種shader的結(jié)構(gòu)如下圖,他們的不同點都在SubShader里面 

這里寫圖片描述

因為Unity推薦Surface Shader,所以文章直接分析Surface Shader的用法,其他兩種shader就不做過多介紹了。

三、Surface Shader語法

在Unity的項目面板中直接創(chuàng)建一個Stander surface shader,默認(rèn)生成的代碼如下

Shader "Custom/DiffuseShader" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)       //設(shè)置一個默認(rèn)的顏色值
        _MainTex ("Albedo (RGB)", 2D) = "white" {}  //默認(rèn)的白色紋理
        _Glossiness ("Smoothness", Range(0,1)) = 0.5  //默認(rèn)的光澤度
        _Metallic ("Metallic", Range(0,1)) = 0.0    //金屬光澤度
    }
    SubShader {
        Tags { "RenderType"="Opaque"}
        LOD 200
 
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows
 
        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
 
 
        fixed4 _Color;
        sampler2D _MainTex;
        half _Glossiness;
        half _Metallic;
 
 
        struct Input {
            float2 uv_MainTex;
        };
 
 
 
        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

接下來我來介紹一下這段代碼

Properties {}

Properties{}是定義著色器屬性的,在這里定義的屬性將被作為輸入提供給所有的子著色器。屬性定義的格式如下

_Name(“Display Name”, type) = defaultValue[{options}]

_Name代表的是屬性名,如Color,MainTex,Glossiness ,Metallic 等

”Display Name”則是在Inspector中顯示的名字

type代表屬性:

Color - 一種顏色,由RGBA(紅綠藍和透明度)四個量來定義;

2D - 一張2的階數(shù)大小(256,512之類)的貼圖。這張貼圖將在采樣后被轉(zhuǎn)為對應(yīng)基于模型UV的每個像素的顏色,最終被顯示出來;

Rect - 一個非2階數(shù)大小的貼圖;

Cube - 即Cube map texture(立方體紋理),簡單說就是6張有聯(lián)系的2D貼圖的組合,主要用來做反射效果(比如天空盒和動態(tài)反射),也會被轉(zhuǎn)換為對應(yīng)點的采樣;

Range(min, max) - 一個介于最小值和最大值之間的浮點數(shù),一般用來當(dāng)作調(diào)整Shader某些特性的參數(shù)(比如透明度渲染的截止值可以是從0至1的值等);

Float - 任意一個浮點數(shù);

Vector - 一個四維數(shù);

這段默認(rèn)Properties在Inspector中的顯示效果如下 

這里寫圖片描述

SubShader{}

Tags :tags標(biāo)簽是三種類型的shader都具有的標(biāo)簽,它決定了硬件什么調(diào)用該子著色器

Tags標(biāo)簽里面默認(rèn)的“RenderType”=”O(jiān)paque”,是告訴系統(tǒng)應(yīng)該在渲染非透明物體時調(diào)用這個SubShader

“RenderType”=”Transparent”表示在渲染含有透明效果的物體時調(diào)用該Sunshader,

Tags里面還有許多其他的我們可選的標(biāo)簽

①.”Queue”:定義渲染順序。預(yù)制的值有這些 

    ”Background”。值為1000。比如用于天空盒。

    ”Geometry”。值為2000。大部分物體在這個隊列。不透明的物體也在這里。

    ”AlphaTest”。值為2450。已進行AlphaTest的物體在這個隊列。 

    ”Transparent”。值為3000。透明物體。 

    ”O(jiān)verlay”。值為4000。比如鏡頭光暈。 

    用戶可以定義任意值,比如”Queue”=”Geometry+10”

②“RenderType”:定義渲染類型。預(yù)制的值有這些

    ”O(jiān)paque”:絕大部分不透明的物體都使用這個; 

    ”Transparent”:絕大部分透明的物體、包括粒子特效都使用這個; 

    ”Background”:天空盒都使用這個; 

    ”O(jiān)verlay”:GUI、鏡頭光暈都使用這個; 

③”ForceNoShadowCasting”:定義物體是否有陰影效果

    “true”。表示有陰影

    “false”。表示沒有陰影

LOD:Level of Detail的縮寫,它表示著色器的細(xì)節(jié)層次效果。在某些硬件比較差的系統(tǒng)上,我們可以設(shè)置一個低一點的值,減少細(xì)節(jié)的顯示。Unity內(nèi)置shader的LOD值如下

  • VertexLit kind of shaders = 100
  • 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

從CGPROGRAM 到ENDCG這一部分就這這個shader的核心內(nèi)容了

#pragma surface surf Standard fullforwardshadows

這段編譯指令聲明了我們要寫一個Surface Shader,并指定了光照模型。它的寫法是這樣的

#pragma surface surfaceFunction lightModel [optionalparams]

surface - 聲明的是一個表面著色器surfaceFunction - 著色器代碼的方法的名字lightModel - 使用的光照模型。

這段代碼默認(rèn)的surfaceFunction為surf,我們可以在源碼的底部看到在這兒聲明了的surf函數(shù)。默認(rèn)的lightModel為Standard。

下面我先介紹一下lightModel光照模型

  • Lambert:該光照模型能很好的表示粗糙表面的光照,但不能表現(xiàn)出鏡面反射高光
  • Toon:最近在游戲中常用的風(fēng)格之一即是Toon shading(又稱 cel shading).這是一種非逼真渲染風(fēng)格,通過改變了光在一個模型上反射實際情況來給人以手繪的感覺
  • BlinnPhong:仿真鏡面反射材料
  • Standard:Unity5中默認(rèn)的光照模式是Standard, 其引入了 物理渲染 (PBR), 但是與其它光照模型沒有什么不同。相比于朗伯反射, PBR提供了一個更加逼真的光線物體作用模型,PBR考慮了材料的物理屬性, 比如能量守恒以及光的散射

接下來的這段代碼

fixed4 _Color;
sampler2D _MainTex;
half _Glossiness;
half _Metallic;

我們可以發(fā)現(xiàn) _Color,_MainTex,_Glossiness,_Metallic都shader屬性的聲明,在上面的Properties 中已經(jīng)聲明過了這些屬性,但是在這段CG程序,要想訪問在Properties中所定義的變量的話,必須使用和之前變量相同的名字再次進行聲明,其實就是鏈接在上面properties中聲明的屬性。

我再來介紹一下shader中常用的數(shù)據(jù)類型

3種基本數(shù)值類型:float、half和fixed。 
這3種基本數(shù)值類型可以再組成vector和matrix,比如half3是由3個half組成、float4x4是由16個float組成。

float:32位高精度浮點數(shù)。 
half:16位中精度浮點數(shù)。范圍是[-6萬, +6萬],能精確到十進制的小數(shù)點后3.3位。 
fixed:11位低精度浮點數(shù)。范圍是[-2, 2],精度是1/256。 
Sampler2D:2D紋理屬性

接下來就是Input結(jié)構(gòu)體

struct Input {
    float2 uv_MainTex;
};

這個結(jié)構(gòu)體和surf函數(shù)中的另一個參數(shù)inout結(jié)構(gòu)體是相對的,一個代表輸入,一個代表輸出。我們可以這樣理解這兩個結(jié)構(gòu)體,你定義輸入數(shù)據(jù)結(jié)構(gòu)(Inputs Struct)、編寫自己的Surface函數(shù)處理輸入、最終輸出修改過后的SurfaceOutput。Input其實是需要我們?nèi)ザx的結(jié)構(gòu),所以我們可以把所需要參與計算的數(shù)據(jù)都放到這個Input結(jié)構(gòu)中,傳入surf函數(shù)使用

默認(rèn)的Input結(jié)構(gòu)體中有一個uv_MainTex參數(shù),代表了紋理的UV值,我們便可以在surf函數(shù)中直接使用這個參數(shù)了。

知道了Input的結(jié)構(gòu)體,我們在來看看Output的結(jié)構(gòu)體

struct SurfaceOutput
{
    fixed3 Albedo;  // diffuse color  漫反射的顏色值。
    fixed3 Normal;  // tangent space normal, if written 法線坐標(biāo)
    fixed3 Emission;  //自發(fā)光顏色
    half Specular;  // specular power in 0..1 range 鏡面反射系數(shù)
    fixed Gloss;    // specular intensity   光澤系數(shù)
    fixed Alpha;    // alpha for transparencies  透明度系數(shù)
};

現(xiàn)在我們在來看看surf函數(shù)里面的內(nèi)容,就已經(jīng)能夠看懂了

我們現(xiàn)在在來看看surf函數(shù)里面的代碼,就能知道里面是什么意思了

void surf (Input IN, inout SurfaceOutputStandard o) {
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;               //將物體顯示的漫反射顏色設(shè)置成在紋理的顏色值
    o.Metallic = _Metallic;         //將物體顯示的金屬光澤設(shè)置成在properties中定義的光澤
    o.Smoothness = _Glossiness;     //設(shè)置物體顯示的光滑度
    o.Alpha = c.a;                  //設(shè)置物體顯示的透明度
}

以上就是淺談Unity中的Shader的詳細(xì)內(nèi)容,更多關(guān)于Unity Shader的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺析C# 基礎(chǔ)語法的使用

    淺析C# 基礎(chǔ)語法的使用

    本篇文章對C#中基礎(chǔ)語法的使用。進行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • C#調(diào)用SQL?Server中有參數(shù)的存儲過程

    C#調(diào)用SQL?Server中有參數(shù)的存儲過程

    這篇文章介紹了C#調(diào)用SQL?Server中有參數(shù)存儲過程的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Unity腳本自動添加頭部注釋的全過程

    Unity腳本自動添加頭部注釋的全過程

    在一些公司需要代碼嚴(yán)格的管理,有時候會需要用到每個腳本的頭部做一些介紹,所以下面這篇文章主要給大家介紹了關(guān)于Unity腳本自動添加頭部注釋的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • 如何在datatable中使用groupby進行分組統(tǒng)計

    如何在datatable中使用groupby進行分組統(tǒng)計

    如何在datatable中進行分組,并且計算分組后每組的數(shù)量,考慮了一下,可以使用LINQ來實現(xiàn)datatable分組,需要的朋友可以參考下
    2015-08-08
  • C#使用NPOI讀取excel轉(zhuǎn)為DataSet

    C#使用NPOI讀取excel轉(zhuǎn)為DataSet

    這篇文章主要為大家詳細(xì)介紹了C#使用NPOI讀取excel轉(zhuǎn)為DataSet,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C# wpf Brush轉(zhuǎn)Hex字符串的實例代碼

    C# wpf Brush轉(zhuǎn)Hex字符串的實例代碼

    這篇文章主要介紹了C# wpf Brush轉(zhuǎn)Hex字符串的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C#使用RestClient調(diào)用Web API

    C#使用RestClient調(diào)用Web API

    這篇文章介紹了C#使用RestClient調(diào)用Web API的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#實現(xiàn)在窗體上的統(tǒng)計圖效果

    C#實現(xiàn)在窗體上的統(tǒng)計圖效果

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)在窗體上的統(tǒng)計圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • c#實現(xiàn)圖片二值化例子(黑白效果)

    c#實現(xiàn)圖片二值化例子(黑白效果)

    這篇文章主要介紹了c#實現(xiàn)圖片二值化例子,圖像二值化就是將圖像上的像素點的灰度值設(shè)置為0或255,也就是將整個圖像呈現(xiàn)出明顯的黑白效果,需要的朋友可以參考下
    2014-08-08
  • C#獲取日期的星期名稱實例代碼

    C#獲取日期的星期名稱實例代碼

    本文通過實例代碼給大家介紹了基于c#獲取日期的星期名稱,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-08-08

最新評論