网站改版 百度影响,网站建设详细报价,wordpress 萌主题下载,1688企业网站建设0 、分析
在前向渲染中#xff0c;对于逐像素光源来说#xff0c;①ForwardBase中只计算一个平行光#xff0c;其他的光都是在FowardAdd中计算的#xff0c;所以为了能够渲染出其他的光照#xff0c;需要在第二个Pass中再来一遍光照计算。
而有所区别的操作是#xff0… 0 、分析
在前向渲染中对于逐像素光源来说①ForwardBase中只计算一个平行光其他的光都是在FowardAdd中计算的所以为了能够渲染出其他的光照需要在第二个Pass中再来一遍光照计算。
而有所区别的操作是②FowardAdd的Pass要能够针对 不同类型的光源 做出不同的计算方法因为在这个pass中要处理的就不仅仅是一个平行光了各种灯光都有可能。 虽然所有光在本质上照亮的原理都是一样的但由于他们的 形式 有点不同从宏观来看 参数会有所不同例如平行光是没有衰减的放置在不同位置也是没有区别的而点光源恰恰相反光亮与光源的位置关系是紧密挂钩的。 所以内容分为两个部分1. 两种光在计算上有何不同2. 如何利用 变体 来实现不同分支的计算。 一、平行光与点光源的不同
1. 光的方向
形式的区别不再赘述而在shader中的区别在于虽然他们的光源数据都是存储在 _WorldSpaceLightPos0 中的但是一个表示光的方向 而另一个表示光的位置。
对于平行光来说_WorldSpaceLightPos0.xyz就能表示光的方向w为0
对点光源来说_WorldSpaceLightPos0.xyz表示的是光的位置w为1而光的方向需要 再减去物体顶点位置 得到。 2. 光的衰减
对于平行光来说是没有光的衰减的
对于点光源来说光会随着距离衰减其衰减与 距离平方的倒数 成正相关 [球的表面积公式为4ΠR² ] 。 二、着色器变体
着色器变体的分支 结合了静态#if 宏定义和动态if 语句判断的特点编译时会先生成多个版本的静态分支运行时再动态地选择要执行的版本。 三、 核心操作
1. 第一个ForwardBase的pass获取光照实现PBS
//PBS
UnityLight directLight (UnityLight)0;
directLight.color _LightColor0.xyz;
directLight.dir l;UnityIndirect indirectLight (UnityIndirect)0;
indirectLight.diffuse 0;
indirectLight.specular 0;return UNITY_BRDF_PBS(albedo, _SpecColor, OneMinusReflectivity, _SpecPower, n, e, CreateLight(i), indirectLight ); 2. 复制出第二个ForwardAdd的pass 这里代码的复用我使用了 Unity Shader代码复用的2个方法-CSDN博客 中抽离为cginc的方法。 3. ForwardAdd中创建出两个变体分支 4. 实现点光源不同的地方 将获取直接光照的代码封装成一个单独的函数实现其两个分支的不同算法。
UnityLight CreateLight(v2f i){UnityLight directLight (UnityLight)0;#if defined(POINT)float3 lightVec _WorldSpaceLightPos0.xyz - i.posWorld;//光方向#elsefloat3 lightVec _WorldSpaceLightPos0.xyz ;#endif//float3 att 1 / (1 dot(lightVec, lightVec));//光的衰减和距离平方的倒数成正相关1是为了防曝光UNITY_LIGHT_ATTENUATION(att, 0, i.posWorld);directLight.color _LightColor0.rgb * att;directLight.dir normalize(lightVec);return directLight;
}