关闭

Unity3d shader编程 Forward渲染路径

标签: shader渲染unity3d
1084人阅读 评论(0) 收藏 举报

接着昨天写的Unity3d shader编程 VertexLit渲染路径 今天动笔另一个Camera的渲染模式Forward的shader pass编程
//另外对昨天写的文章进行了稍许的内容增加和解释,以便读者更好理解。


老生重提,学过shader编程的同学应该知道,一个特效的形成是由3部分组成(像魔戒三部曲一样)。物体材质+光源+视摄像机共同渲染的结果。物体材质是我们可以编程的如何接收光,反射,折射等,这一部分涉及物理光学(突然好高大上),计算机靠数学函数模拟光照的特征,计算出光照强度颜色等,最终反映到屏幕上被肉眼接收。那摄像机有vertexlit,forward,deferred三种模式干嘛? 其实摄像机就是统一规定屏幕内的物体都是以什么方式被渲染的,VertexLit顶点方式则全部用物体材质中的vertex path渲染路径去刻画每一个物体,如果(当前显示)摄像机用forward模式,则查找物体材质shader程序中forward base/forward add path去刻画物体,如果找不到则还是用vertex path去刻画。如果(当前显示)摄像机用deferred模式,则查找物体材质shader程序中PrepassBase/PrepassFinal path(这里不是deferred开头额。)方法去刻画物体,找不到则寻找forward base/forward add path去刻画物体,再找不到则使用最低级的vertex path去渲染,再找不到?有个FallBack "Diffuse"就是最终使用unity系统默认渲染方法来渲染..您就甭管了... 

所以摄像机的渲染模式就像一个总开关... 而材质的渲染路径path就是总开关下的各种串并联电路,决定哪种渲染方式合适,而光源有两种光照vertex/pixel和材质渲染路径共同决定如何显示,总不能光源是vertex顶点的,而要求材质渲染用deferred的逐像素点渲染吧?这时候就会自动调整到适合光源的vertex path路径下渲染。。 而vertex顶点渲染硬件开销小..废话么,都不是每个像素点运算的,只是顶点插值出来的均值,所以游戏中主要光源应该用pixel逐像素点刻画,而次要光源(啥叫次要,比如太阳下的小星星,你就自己琢磨吧)就可直接设置成vertex模式的,强制材质物体在使用该光源时使用vertex path渲染来减少运算开销,增加帧率!有舍必有得嘛。 

物体材质+光源+视摄像机的关系全部说完,接下来是正文..序言很长,但必须理清!如果不理解可看完正文回头来看这段解释,深度理解三者关系,才能在写代码时心中有丘壑。

Forward/FowardAdd Pass

这两种渲染路径在摄像机为vertexLit模式下都不被支持,因为他们更高级. 并且FowardAdd是Forward的补充,所以叫Add,如果Forward路径不存在,则ForwardAdd即使被写进去了,也是不被调用得。在摄像机为Forward和Deferred模式下,Forward的pass均能被正常渲染。因为Deferred限定更高级的渲染模式,一旦没找到Deferred相关的PrepassBase/PrepassFinal 的渲染方式则会使用Forwardbase/ForwardAdd就像序言说的那样(什么还没看过?先滚过去通读一遍再回来)。

上文说到三种光源变量在shader pass中被获取(当然先要#include “UnityCG.cginc”,#include “Lighting”)
(1) _WorldSpaceLightPos0/_LightColor0

  1. 光源不存在pixel ——现在这个环境是在Forward pass下,所以该变量能获取才对,(上一章节内容),但是如果光源为vertex则强行改变物体材质的渲染方式降低为vertex渲染方式(但是别误会 不会运行vertex pass),所以_WorldSpaceLightPos0/_LightColor0是获取不到值得。ForwardBase中没有值,ForwardAdd则不会被运行。

  2. 存在pixel平行光没有pixel点光源 ——ForwardBase中_WorldSpaceLightPos0/_LightColor0获取到了值,但是FowardAdd这个高级附加功能依旧没有被运行

  3. 存在pixel点光源没有pixel平行光 ——ForwardAdd Pass包含光源数据且被执行。ForwardBase内_WorldSpaceLightPos0有数据,但是对应_LightColor0没有,所以组合光照(亮度*颜色)还是黑色。等于没用。

  4. 多种类型的Pixel光源时 ——-视情况而定。Pixel平行光被ForwardBase Pass所处理,并且只能处理一个最强亮度的Pixel平行光,即使有很多…剩余其他的Pixel平行光则被推倒ForwardAdd Pass中处理,如果有点光源排在平行光之后处理。(当然都要是Pixel模式的,而且全都会被处理,一一处理,顺序还是亮度强先处理,平行光先处理)。如果没有平行光,只有Pixel点光源的时候,ForwardBase Pass永远只能处理一个光源,而ForwardAdd Pass能处理无限多…理论上。例如有3个Pixel 点光源(即使有平行光也是无效的vertex光源,就和没有一样),亮度最大的点光源被ForwardBase处理,其他点光源被排到ForwardAdd中处理。

(2)unity_4LightPos[X,Y,Z]0 / unity_LightColor[4]

  1. 包含4个Vertex类型的点光源,如果一个个把点光源改成平行光,信息就会从变量中一一消失,Unity会清空该对应数据。

  2. 逐个将Vertex点光源改为Pixel点光源,被改为Pixel点光源的信息会排序靠前!因为Pixel类型的光源相对重要!

  3. 在ForwardAdd Pass内 unity_4LightPos[X,Y,Z]0组合和对应的颜色数据只包含Vertex点光源。注意不要重复计算

(3)unity_LightPosition[4] / unity_LightColor[4] 使用相同的Color变量

  1. 所有情况下都是空数据….
0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:28040次
    • 积分:493
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:5篇
    • 译文:1篇
    • 评论:9条
    最新评论