之前也说过引擎能不能提供一个一般化的开发环境给使用者, 这样使用者只需要指定他要的开发环境, 就能用它最熟悉的方式去写Shader了.
从提供者的角度来看, 因为有太多的应用场景无法确定, 所以提供无数多套的设定才能满足需求, 比如你要用来做一般Shader还是用来做后处理用, 后处理中的顶点位置在片元阶段的插值得到的就绝对不是所显示的对象的世界坐标.
从使用者的角度来说, 在经过多平台, 多版本的迭代之后, 要维护的代码量只会越来越多, 到最后简直不知道怎样去维护了, 举个例子 :
0. 变量声明
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 有拉伸位移的代码 -- 多用于物体渲染
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; }
3. 我要用在VR上! -- 官方后处理效果可见
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, 被引擎强制处理了)
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的后处理上! -- 我已经飘了!
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的从左下角开始计算, 这些不就又能省掉了么, 太能折腾了.
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!