一、
看到UNITY論壇里有些人求unity shader序列幀動畫,寫shader我擅長啊,就順勢寫了個CG的shader。
代碼很簡單,就是變換UV采樣序列幀貼圖,美術配置行數列數以及變換速度。
二、
下午看到美術場景中有透明排序的問題,隨即詢問他們為啥地面一個大片兒要用透明材質,使用鏤空多爽快,一會兒美術跑來問我,unity里沒提供鏤空的shader,我打開編輯器愁了一眼,還真的基本都是透明材質,QQ上密了專家答道,在某些移動平台中,鏤空會比透明更費一些,搞了幾年渲染,這世界觀崩潰的,專家的這話空穴來風,其在各種真機上有過測試,給出的理由是:OPENGLES2標准沒有支持AlphaTest,都是在Shader里面用discare搞,移動硬件實現千奇百怪,至少IPHONE4這樣的基線機器鏤空效率非常慘淡。專家還給了一張benchMark圖標為證。
看到UNITY論壇里有些人求unity shader序列幀動畫,寫shader我擅長啊,就順勢寫了個CG的shader。
代碼很簡單,就是變換UV采樣序列幀貼圖,美術配置行數列數以及變換速度。
Shader "HELLOHUAN/Hello_Sequence" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} _SizeX ("列數", Float) = 4 _SizeY ("行數", Float) = 4 _Speed ("播放速度", Float) = 200 } SubShader { Tags { "RenderType"="Opaque"} LOD 200 CGPROGRAM #pragma surface surf Lambert alpha sampler2D _MainTex; fixed4 _Color; uniform fixed _SizeX; uniform fixed _SizeY; uniform fixed _Speed; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { int index = floor(_Time .x * _Speed); int indexY = index/_SizeX; int indexX = index - indexY*_SizeX; float2 testUV = float2(IN.uv_MainTex.x /_SizeX, IN.uv_MainTex.y /_SizeY); testUV.x += indexX/_SizeX; testUV.y += indexY/_SizeY; fixed4 c = tex2D(_MainTex, testUV) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; //o.Albedo = float3( floor(_Time .x * _Speed) , 1.0, 1.0); } ENDCG } Fallback "Transparent/VertexLit" }
shader,UI如下:
二、
下午看到美術場景中有透明排序的問題,隨即詢問他們為啥地面一個大片兒要用透明材質,使用鏤空多爽快,一會兒美術跑來問我,unity里沒提供鏤空的shader,我打開編輯器愁了一眼,還真的基本都是透明材質,QQ上密了專家答道,在某些移動平台中,鏤空會比透明更費一些,搞了幾年渲染,這世界觀崩潰的,專家的這話空穴來風,其在各種真機上有過測試,給出的理由是:OPENGLES2標准沒有支持AlphaTest,都是在Shader里面用discare搞,移動硬件實現千奇百怪,至少IPHONE4這樣的基線機器鏤空效率非常慘淡。專家還給了一張benchMark圖標為證。

某些平台下,Blend幀數高
我自然是信了。還是給美術寫了個對應的鏤空shader,並給出建議,透明鏤空效率都很誇張,最好還是美術通過挖洞來實現鏤空。(這公司的美術還是不那么矯情的,編輯器一天dump十幾次啥話不說,大家都苦逼,何必為難)。
寫Shader過程我的感覺,為啥渲染狀態沒有暴漏在外邊給美術調節,非得寫在Shader里么?unity渲染也支持透明排序補間,但是必須在Shader中寫明“transparence + 1”的代碼。這尼瑪我要寫N個Shader來實現相同的Shader計算,但是不同的渲染狀態的效果么?增加了文件資源的數量不說,這Shader切換的消耗可比渲染狀態切換的消耗大吧,難道移動顯卡架構?OGL與DIRECTX繪制差別這么大?unity好歹也是跨平台的引擎啊。
不得不贊嘆起在以前公司參與寫過的Shader系統,想念那個雖然是抄襲Unreal,讓美術所見所得有寫程序般快感的通過拉結點連線連拓撲關系來寫Shader的Shader模版編輯器,還有個可以具體實例資源單獨配置的Shader實例編輯器,調控某些shader變量及渲染狀態,渲染時按shader類型排序渲染。還是自己寫引擎效率高啊。
不過當時的Shader編輯器一出,也出現了制作上的問題,一是:美術創造能力太強大了,顏色貼圖的RGB都能進行矩陣變換,最后連得算法無法理解卻可以有其認為“炫酷”的效果。二是,shader創造的太多不好管理了,改動起來對現有資源影響較大,增加審核模版的工作和添加新的模版的工作又光榮的落在了我等圖形程序員的肩上,工具化后還是苦逼。
寫Shader過程我的感覺,為啥渲染狀態沒有暴漏在外邊給美術調節,非得寫在Shader里么?unity渲染也支持透明排序補間,但是必須在Shader中寫明“transparence + 1”的代碼。這尼瑪我要寫N個Shader來實現相同的Shader計算,但是不同的渲染狀態的效果么?增加了文件資源的數量不說,這Shader切換的消耗可比渲染狀態切換的消耗大吧,難道移動顯卡架構?OGL與DIRECTX繪制差別這么大?unity好歹也是跨平台的引擎啊。
不得不贊嘆起在以前公司參與寫過的Shader系統,想念那個雖然是抄襲Unreal,讓美術所見所得有寫程序般快感的通過拉結點連線連拓撲關系來寫Shader的Shader模版編輯器,還有個可以具體實例資源單獨配置的Shader實例編輯器,調控某些shader變量及渲染狀態,渲染時按shader類型排序渲染。還是自己寫引擎效率高啊。
不過當時的Shader編輯器一出,也出現了制作上的問題,一是:美術創造能力太強大了,顏色貼圖的RGB都能進行矩陣變換,最后連得算法無法理解卻可以有其認為“炫酷”的效果。二是,shader創造的太多不好管理了,改動起來對現有資源影響較大,增加審核模版的工作和添加新的模版的工作又光榮的落在了我等圖形程序員的肩上,工具化后還是苦逼。
前端時間研究GB,GameBryo的ShaderTree的設計很好,跟以前搞過的Shader編輯器思想如出一轍,每一個結點包含自己的INPUT,ShaderConst,VSCOde,PSCode,各個結點通過輸入輸出連接。問題也很多:
1、太不好擴展了,我曾經嘗試在ShaderTree里加一個勾邊光的計算結點,費了很大的勁兒。
2、排列組合太多,最后生成的shader通過各種開關映射稱GUID保存到本地,編譯為2進制文件,這個機制我倒是也用過。就是排列組合發布的時候數量不可控了(Shader肯定要預先生成的)。
GB的整個Shader系統很好擴展,既可以默認使用ShaderTree,又可以自定義Shader,支持挺多語言。
維護的Gamebryo的項目,整個項目下來就用了二十多個Shader(沒有使用GB自帶的ShaderTree),常用的十幾個,美術就在這里邊挑,能用就用,不能完成效果也得用,管理的也還好,只是擴展起來不便。UNITY也提供了一些內置的Shader,由美術來選擇使用,也支持自己增加CG或Shader代碼,但是要遵循其ShaderLib格式。
之前曾經一度鄙視過以前的shader流水線編輯,感覺方便了美術,卻引來了更多的工程性問題,但是UNITY的方式也太不負責任,究竟啥樣的方案更適合產品,只有產品本身知道了。