以前也說過引擎能不能提供一個通常化的開發環境給使用者, 這樣使用者只須要指定他要的開發環境, 就能用它最熟悉的方式去寫Shader了.app
從提供者的角度來看, 由於有太多的應用場景沒法肯定, 因此提供無數多套的設定才能知足需求, 好比你要用來作通常Shader仍是用來作後處理用, 後處理中的頂點位置在片元階段的插值獲得的就絕對不是所顯示的對象的世界座標.編輯器
從使用者的角度來講, 在通過多平臺, 多版本的迭代以後, 要維護的代碼量只會愈來愈多, 到最後簡直不知道怎樣去維護了, 舉個例子 : spa
0. 變量聲明code
sampler2D _MainTex; half4 _MainTex_ST; half4 _MainTex_TexelSize; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; };
1. 初始代碼對象
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; }
2. UV 有拉伸位移的代碼 -- 多用於物體渲染blog
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; }
3. 我要用在VR上! -- 官方後處理效果可見ip
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST); return o; }
4. 我要用在後處理上! -- 後處理對於屏幕起始點敏感開發
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) { o.uv.y = 1 - o.uv.y; } #endif return o; }
5. 後處理UV有拉伸位移! -- 我都不知道這段代碼對不對了! (後處理的縮放係數始終爲1, 偏移始終爲0, 被引擎強制處理了)it
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) { o.uv.y = 1 - o.uv.y; } #endif return o; }
6. 我要繼續用到VR的後處理上! -- 我已經飄了!class
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST); #if UNITY_UV_STARTS_AT_TOPif (_MainTex_TexelSize.y < 0.0) o.uv.y = 1.0 - o.uv.y; #endif return o; }
這些不是隨便臆想出來的, 它的官方代碼也是同樣的, 隨着版本的更迭提供了更多的目標平臺, 因此官方的代碼也在一直變化, 這只是單一個UV的變量問題, 其它問題比這多的多......有一份代碼就要改一份, 各類各樣Shader用的多的項目組估計要昇天的.
像上面的UV變量, 正常來講你有 _MainTex_ST 的設定的話, 必定會用 TRANSFORM_TEX(v.uv, _MainTex); 的吧, 或者我使用VR 而且使用Single Pass模式的話, 確定要去調用 UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST); 的吧, 就不能在頂點階段傳入的時候給我自動計算好嗎, 每次還要開發者本身去加宏判斷平臺嗎, 這些在編輯器下加個平臺選項不就行了嗎.
像 UNITY_UV_STARTS_AT_TOP 這種判斷, 應該是每一個屏幕後處理都要加的吧, 看看它出現的次數, 若是給使用者設定這個Shader是使用D3D或者OpenGL標準的話, 咱們就能明確知道屏幕(0,0)點的位置在哪了, 習慣opengl的就從左上角開始計算, 習慣D3D的從左下角開始計算, 這些不就又能省掉了麼, 太能折騰了.