GrabPass截屏
可以用來截屏,截屏后把紋理傳給下一個通道使用。
1:使用抓屏通道, GrabPass {} 或 GrabPass { “ 紋理名稱”}; 使用GrabPass {}后,可以用_GrabTexture訪問截屏的紋理
2: 后續的Pass通道使用這個抓屏;
3: 編寫案例
(1): 創建一個頂點片元着色器;
(2): 將這個着色器放到Overlay隊列
(3): 使用GrabPass通道截屏,並定義好變量來接收
(3): 設置頂點的UV坐標;
(4): 着色使用截圖的紋理
GrabPass截屏案例
1.創建好Unity工程目錄
2.創建一個平面plane和一個立方體cube,給cube一個材質red,把red拖進cube的材質屬性中
3.再創建一個平面show,豎起來放在旁邊,等下用來顯示截屏紋理
4.在resources文件夾下面創建shaders文件夾
5.打開shaders文件夾,創建一個用於頂點片元着色的shader,create---->shader---->unlit shader,重命名為GrabShader
6.打開GrabShader
第一步:先把第一行改成Shader "Custom/GrabShader",這樣才能在編輯器里面顯示這個shader
第二步:把渲染隊列拉到最高overlay
Tags { "RenderType"="Opaque" "Queue"="Overlay" }
第三步:使用截屏通道
Shader "Custom/GrabShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "Queue"="Overlay" }//把渲染隊列拉到最高overlay LOD 100 // GrabPass {} // 截圖通道, 后面使用_GrabTexture訪問截屏紋理 // end Pass { name "ONE" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _GrabTexture;//使用前重新聲明一下 float4 _GrabTexture_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _GrabTexture);//使用 return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_GrabTexture, i.uv);//使用 return col; } ENDCG } } }
7.創建一個材質GrabShader,shader屬性設置為Custom/GrabShader
8.show平面關聯材質球GrabShader
9.運行起來,Game視圖里面的plane視圖上面顯示出截屏紋理
常用的gcinc
系統自帶的類似於語言里面的.h文件,是庫函數,在Unity-->Edit-->Data-->CGIncludes;查看
1:cginc文件: 宏,幫助函數等,放在CGIncludes下面,開發人員可以開發自己的cginclude文件
2:常用的cginc文件:
HLSL.Support.cginc 協助多平台開發的一些宏等,自動包含
UnityShaderVarirables.cginc 全局變量,自動包含;
UnityCG.cginc 常用的幫助函數;
AutoLight.cginc 光照和陰影功能;
Lighting.cginc 表面着色器的光照模型;
TerrainEngine.cginc 地形植被的光照着色函數;
UnityCG.gcinc常用函數
1:UnityWorldSpaceViewDir: 給定對象空間的頂點位置朝向攝像機方向的世界坐標空間方向;
2: ObjSpaceViewDir: 給定對象空間的頂點位置朝向攝像機方向的對象空間方向;
3: ParallaxOffset: 計算用於視差法線貼圖的UV偏移量;
4: Luminance: 將顏色轉為亮度;
5: DecodeLightmap: 從光照貼圖中解碼顏色;
6: float EncodeFloatRGBA(float4 rgba): 將RGBA顏色編碼為[0,1)的浮點數;
7: float4 DecodeFloatRGBA(float v): 將一個浮點數解碼為RGBA的顏色;
8: UnityWorldSpaceLightDir 給定對象空間的頂點位置到光源的世界坐標空間方向;
9: ObjSpaceLightDir: 給定對象空間的頂點位置到光源的對象空間方向;
UsePass 復用
1:編寫過的pass可以重復使用,借助UsePass “ShaderPath/PASS_NAME”
2:PASS名字要大寫;
3: Pass {
name “ONE” //不要寫到cgprogram里面
}
4: UsePass “Custom/ShaderName/ONE”
multi_compile多版本控制
1: 通過multi_compile編譯多個版本的shader;
2: #pragma multi_compile MY_multi_1 MY_multi_2;
3: #ifdef MY_multi_1 #endif
4: Shader.EnableKeyword(“ MY_multi_1”);
5: Shader.DisableKeyword(“MY_multi_2”); 控制shader編譯出不同的版本;
multi_compile多版本控制實例
1.打開shaders文件夾,創建一個用於頂點片元着色的shader,create---->shader---->unlit shader,重命名為MultiShader
2.打開MultiShader
第一步:先把第一行改成Shader "Custom/MultiShader",這樣才能在編輯器里面顯示這個shader
第二步:
Shader "Custom/MultiShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // 定義這個的兩個開關,告訴有兩個版本的shader #pragma multi_compile MY_multi_1 MY_multi_2 #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col; // sample the texture #ifdef MY_multi_1//版本1 col = fixed4(1.0, 0.0, 0.0, 1.0); #endif #ifdef MY_multi_2//版本2 col = fixed4(0.0, 0.0, 1.0, 1.0); #endif return col; } ENDCG } } }
3.創建一個材質MultiShader,設置它的shader屬性為Custom/MultiShader
4.創建一個立方體cube,把材質MultiShader拖進cube
5.創建一個腳本MultiShader,掛載在立方體cube下面
打開MultiShader.cs
using UnityEngine; using System.Collections; public class MulShader : MonoBehaviour { // Use this for initialization void Start () { Shader.EnableKeyword("MY_multi_2");//打開版本2 Shader.DisableKeyword("MY_multi_1");//關閉版本1 } // Update is called once per frame void Update () { } }
移動平台優化
1: 代碼優化:
預先計算好對應的值 sqrt(2) --> 根號2 --> 1.414..;
放心的使用向量相關操作,叉積,點擊,基本都是硬件實現,很高效;
盡量減少函數調用減少開銷;
2: 盡可能的計算放在頂點着色器中,頂點着色器的調用頻率遠低於片着色器;
3: 幾何復雜度考量:在IOS平台視口內的頂點數不要超過100K個,IOS默認的緩沖區就是就是這么大,超過這個數字,底層會做一些操作消耗更多的資源;
4: 紋理大小為 2^n次方大小, 16, 64, 128, 256, 512, 1024;
5: 使用適當的數據類型float < half < fixed; 性能
6: 盡量慎用透明效果,透明效果GPU要逐像素渲染,而且沒有了遮擋剔除的效果,會用到Blend SrcAlpha OneMinusSrcAlpha//SrcAlpha是源因子,OneMinusSrcAlpha是目標因子,產生的各個顏色和各個因子相乘,然后兩個顏色相加