<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Unity3D學習筆記3——Unity Shader的初步使用

      1. 概述

      在上一篇文章《Unity3D學習筆記2——繪制一個帶紋理的面》中介紹了如何繪制一個帶紋理材質的面,并且通過調整光照,使得材質生效(變亮)。不過,上篇文章隱藏了一個很重要的細節——Unity Shader。Shader(著色器)是渲染管線中可被用戶編程的階段,依靠著色器可以控制渲染管線的細節。現代圖像渲染技術,都把Shader封裝成與Material(材質)相關的組件。所以這篇文章,我們就初步學習下在Unity中使用Shader。

      2. 詳論

      2.1. 創建材質

      在上一章中,材質、以及材質相關的資源是在Unity3D編輯器中創建,在C#腳本中直接引用的。這里為了學習使用Shader,我們使用自定義的Shader,可以在C#腳本中創建材質。修改上一章代碼的材質部分:

      Shader shader = Shader.Find("Custom/MainShader");
      Material material = new Material(shader);
              
      Texture2D texture = Resources.Load<Texture2D>("ImageDemo");
      material.mainTexture = texture;
      
      MeshRenderer meshRenderer = newGameObject.AddComponent<MeshRenderer>();      
      meshRenderer.material = material;
      

      可以看到,要創建一個Material,首先得創建一個Shader。我們在Project視圖中右鍵菜單->Create->Standard Surface Shader,創建一個標準表面著色器MainShader:

      imagelink1

      雙擊打開這個Shader,可以看到這個Shader的具體內容。標準著色器很復雜,我們清空里面的內容,填入我們這個更簡單的著色器示例:

      Shader "Custom/MainShader"
      {
          Properties
          {       
              _MainTex ("Texture", 2D) = "white" {}      
          }
          SubShader
          {
              Tags{"Queue" = "Geometry"}
      		
      		Cull Back
      
      		Pass
      		{
      		    CGPROGRAM
          
      			#pragma vertex vert	
      			#pragma fragment frag
      
      			sampler2D _MainTex;
      
      			//頂點著色器輸入
      			struct a2v
      			{
      				float4  position : POSITION;
      				float3  normal: NORMAL;
      				float2  texcoord : TEXCOORD0;	
       			};
      
      			//頂點著色器輸出
      			struct v2f
      			{
      				float4 position: SV_POSITION;
      				float2 texcoord: TEXCOORD0;
      			};
      
      			v2f vert(a2v v)
      			{
      				v2f o;	
      				o.position = mul(UNITY_MATRIX_MVP, v.position);									
      				o.texcoord = v.texcoord;
      
      				return o;
      			}
      
      			fixed4 frag(v2f i) : SV_Target 
      			{
      				return tex2D(_MainTex, i.texcoord);			
      			}
         
      			ENDCG
      		}
          }
          FallBack "Diffuse"
      }
      

      2.2. 著色器

      Unity使用的著色器語言叫做ShaderLab,它是圖形渲染中Shader(例如GLSL,HLSL以及CG)的更高級更抽象一級的封裝。ShaderLab是個非常簡單的說明性描述語言,通過嵌套在花括號中的語義來描述Unity Shader文件。

      2.2.1. 名稱

      通過Shader語義指定Unity Shader的名稱:

      Shader "Custom/MainShader"
      {
      
      }
      

      這個名稱非常重要,在Unity編輯器中需要通過這個名字來引用Shader。

      2.2.2. 屬性

      Shader語義塊的第一個語義塊是Properties語義塊,它連接著材質和Unity3d編輯器,設置了這個屬性就能夠通過材質面板調整材質,調整材質的本質就是調整Shader。Properties的定義通常描述如下:

      Properties {
      	Name ("display name",PropertyType) = DefaultValue
      }
      

      Name指的是在Shader中使用的名稱,display name指的是顯示在材質面板的名稱。PropertyType則有點容易混淆,它指的是顯示在材質面板中的屬性類型,借用一下《Unity Shader入門精要》的圖表:

      imagelink2

      2.2.3. SubShader

      每個Unity Shader都至少包含一個SubShader語義塊,Unity會優先選擇第一個能夠在當前平臺下運行的SubShader作為最終渲染效果的Shader。

      這個語義塊下面又會包含三個語義塊:

      2.2.3.1. 標簽(Tags)

      SubShader的標簽用于用于標識何時以何種方式被渲染到渲染引擎,它由一系列鍵值對組成。Queue是最常用的標簽,用于標識渲染物體在渲染隊列中的位置:
      imagelink3

      我們這里,把這個渲染物體放到Geometry隊列中,這個位置通常放置不透明物體的渲染:

      Tags{"Queue" = "Geometry"}
      

      2.2.3.2. 渲染狀態(RenderSetup)

      渲染狀態用于設置圖形硬件的各種狀態,例如是否應開啟 Alpha 混合或是否應使用深度測試等。在像OpenGL這樣的圖形接口中,通常是以函數的形式進行調用的,Unity3d將其放在Shader里面,也有一定的道理。

      這里的渲染狀態設置成將背面裁剪掉:

      Cull Back
      

      2.2.3.3. 通道(Pass)

      在Pass語義塊中,才是像OpenGL/DirectX中使用的Shader。OpenGL使用的著色器語言叫做GLSL,DirectX使用的著色器語言叫做HLSL,Unity3D則推薦使用Cg語言,這是一種類C語言,與HLSL非常相似。Cg語言代碼段在Pass語義塊中被包裹在CGPROGRAM和ENDCG之間:

      CGPROGRAM
      //...
      ENDCG
      

      2.2.4. 回退(FallBack)

      FallBack定義了一種退化策略,由于不同機器支持的性能特性不同,如果之前的子著色器都不生效,那么就使用這個著色器,通常這個著色器是內置的:

      FallBack "Diffuse"
      

      2.3. 渲染管線

      圖形渲染引擎的渲染管線其實是個內涵非常豐富的概念,再次借用《Unity Shader入門精要》的插圖,渲染管線的描述大致如下:

      imagelink4

      當然只看這個圖是不夠的,但是我們可以直接從代碼層面去了解它。鑲嵌在CGPROGRAM和ENDCG之間的CG代碼,體現的正是渲染管線的思維。

      首先,通過編譯指令,分別指定頂點著色器程序和片元著色器程序:

      #pragma vertex vert	
      #pragma fragment frag
      

      vert就是頂點著色器的函數,在這個著色器程序中指定了計算了頂點坐標和紋理坐標:

      v2f vert(a2v v)
      {
      	v2f o;	
      	o.position = mul(UNITY_MATRIX_MVP, v.position);									
      	o.texcoord = v.texcoord;
      
      	return o;
      }
      

      傳入參數是一個結構體,POSITION,NORMAL,TEXCOORD0是Unity Shader中固定的語義,分別代表這位置、法向量以及紋理坐標,他們也被稱為頂點屬性。還記得在上一篇文章《Unity3D學習筆記2——繪制一個帶紋理的面》中創建Mesh時給Mesh創建的成員變量vertices、uv和normals吧?給他們傳入的數據正是在這里用到了。

      //頂點著色器輸入
      struct a2v
      {
      	float4  position : POSITION;
      	float3  normal: NORMAL;
      	float2  texcoord : TEXCOORD0;	
      };
      

      傳出參數則是另外一個結構體:

      //頂點著色器輸出
      struct v2f
      {
      	float4 position: SV_POSITION;
      	float2 texcoord: TEXCOORD0;
      };
      

      SV_POSITION表示的是裁剪空間坐標,也就是在頂點著色器中計算的頂點值。這個計算內容的內涵也挺豐富的,簡單來說,創建Mesh時的頂點坐標,經過一個模型變換(Model)、視圖變換(View)、投影變換(Projection),最終變成了裁剪空間坐標系中的坐標,體現在著色器中,就是內置的MVP矩陣UNITY_MATRIX_MVP。

      剩下的就是片元著色器函數的部分了。在這個著色器中,_MainTex也就是我們先前創建的,并且傳遞到材質中的紋理,通過將頂點著色器中傳遞過來的紋理坐標進行采樣,得到具體的片元顏色:

      sampler2D _MainTex;
      
      fixed4 frag(v2f i) : SV_Target 
      {
      	return tex2D(_MainTex, i.texcoord);			
      }
      

      最終顯示的效果如下:
      imagelink5

      可以看到這里顯示的就是圖片本身的顏色,這是因為在著色器中只是采樣了圖片的顏色,并沒有光照計算的參與。也就是在圖形引擎中,任何效果的設置只是表象,任何效果的實現都會歸結到著色器中。

      posted @ 2021-08-01 17:38  charlee44  閱讀(1121)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 97se亚洲国产综合自在线观看| 内地自拍三级在线观看| 四虎影院176| 亚洲精品国产精品国在线| 亚洲一区二区三区 无码| 四虎永久精品在线视频| 无码人妻丝袜在线视频| 久久久亚洲欧洲日产国码αv| 开心五月深深爱天天天操| 国产中文字幕在线一区| 精品国产一区二区三区av色诱 | 国产无套乱子伦精彩是白视频| 亚洲av永久无码精品漫画| 一区二区三区无码免费看| 波多野结衣的av一区二区三区| 国产一区在线播放av| 久久精品国产国产精品四凭| 无码伊人66久久大杳蕉网站谷歌| 开心激情站一区二区三区| 亚洲综合日韩av在线| 无码天堂va亚洲va在线va| av在线播放日韩亚洲欧| 99久久精品视香蕉蕉| 亚洲欧美人成网站在线观看看| 麻豆精产国品一二三区区| 亚洲日韩在线中文字幕第一页| 久久久久免费看成人影片| 深夜福利国产精品中文字幕| 成人午夜福利视频后入| 精品午夜福利短视频一区| 51午夜精品免费视频| 精品久久久久久无码人妻蜜桃| 久久精品不卡一区二区| 亚洲日韩国产中文其他| AV最新高清无码专区| 国产乱子伦一区二区三区视频播放| 天天影视色香欲综合久久| 人妻换着玩又刺激又爽| 国内自拍偷拍一区二区三区| 午夜免费无码福利视频麻豆| 在线看片免费人成视久网|