关于UNITY_BRANCH、UNITY_UNROLL的小知识

本文探讨了UNITY_BRANCH和UNITY_UNROLL宏在不同平台上的定义及作用。UNITY_BRANCH在多个平台如D3D11、GLCore等被定义为[branch],用于条件分支控制;在GLES2和其他未知平台则被定义为空,所有分支语句均会执行。UNITY_UNROLL宏在大多数高性能平台被定义为[unroll],用于循环展开优化,但在GLES2和未知平台仅在必要时进行循环展开。

UNITY_BRANCH这个宏在下列平台中被定义为[branch]:

D3D11、GLCore、GLES3、Metal、PSSL、Switch、Vulkan、XBoxOne

意为如果if表达式为false,不执行if中的语句。详见MSDN

而在GLES2和不可识别的平台上被定义为空,则不论表达式的结果是什么,都会执行所有分支的语句。可能是在这类平台上不支持[branch]特性的关系,这一点有待确认。

 

UNITY_UNROLL这个宏在下列平台中被定义为[unroll]:

D3D11、GLCore、GLES3、Metal、PSSL、Switch、Vulkan、XBoxOne

意为基于循环次数展开循环。详见MSDN

而在GLES2和不可识别的平台上被定义为空,根据文档的说明,这种情况下首先尝试不展开循环,如果尝试失败,才使用展开循环的版本。可能是这类平台自身指令数的限制,展开循环容易导致指令数过多,这一点有待确认。

Unity的内置着色器中经常使用UNITY_VPOS_TYPE枚举类型,它表示当前顶点的坐标空间类型。以下是一个使用UNITY_VPOS_TYPE的实例: ```hlsl v2f vert(appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); #if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD) UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.screenPos = ComputeScreenPos(o.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); #if defined(_ALPHATEST_ON) o.alpha = v.color.a; #endif #elif defined(UNITY_PASS_SHADOWCASTER) o.worldPos = mul(unity_ObjectToWorld, v.vertex); #endif return o; } ``` 在这个顶点着色器函数中,我们可以看到在#if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD)条件下,我们通过UNITY_SETUP_INSTANCE_ID(v)和UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o)来设置实例ID和立体视图,然后根据UNITY_VPOS_TYPE的不同,我们可以对o.worldPos和o.vertex进行不同的计算。在这个例子中,我们通过UnityObjectToClipPos(v.vertex)来将顶点坐标从对象空间转换到裁剪空间,并将结果保存在o.vertex中。 需要注意的是,UNITY_VPOS_TYPE枚举类型的取值是根据渲染管线的不同而不同的。在顶点着色器中,我们需要根据当前的渲染管线类型来确定UNITY_VPOS_TYPE的取值,以正确地计算顶点的位置和法线等信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值