以前也说过引擎能不能提供一个通常化的开发环境给使用者, 这样使用者只须要指定他要的开发环境, 就能用它最熟悉的方式去写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的从左下角开始计算, 这些不就又能省掉了么, 太能折腾了.