zoukankan      html  css  js  c++  java
  • Rendering Path

    Rendering Path:渲染路径
      设置:1、Player Setting,2、Camera(会覆盖PlayerSetting中的设置)
      选择:根据渲染内容和目标平台来选择合适的Rendering Path,当一个GPU不能处理Deferred Lighting时,会自动切换到Forward Lighting,当Forward Lighting不支持时,会自动切换到Vertexx Lig。

    (1)Vertex Lit:
      最低真实度但也是最快的的渲染路径,不支持realtime shadows,建议用在旧机器或一些移动平台上。
      所有lighting都基于顶点计算光照在一个pass里完成,不支持所有的基于pixel计算的效果,比如:shadows、normal mapping、light cookies、highly detailed specular highlights。

    (2)Forward Rendering:
      支持一盏方向光的实时阴影。
      最亮的几盏(QualitySetting)光源按像素计算,然后,最多4盏点光源按照逐顶点计算,剩下的都按照SH计算,具体的影响因素:
      (1)Light.RenderMode = Not Important的光源:按照per-vertex或者SH计算;
      (2)最亮(Light.intensity和距离)的directional light:总是per-pixel;
      (3)Light.RenderMode = Important的光源:总是per-pixel计算;
      (4)QualitySetting.PixelLightCount指定了pixel光照的数量,如果基于上述3个规则所产生的pixel light小于此数量,则会有更多的light按照per-pixel计算,以此来降低亮度。
      SH光照:基于vertex计算,但比vertex light要快,它只是一个近似的计算;
          有一点CPU开销,几乎没有GPU开销,很多个SH light和一个SH light的开销完全一样;
          SH lighting非常低频率,所以不要对SH light做太快的transform,SH light只影响diffuse lighting,由于太慢而不支持specular light。

      渲染每个物体的过程:

        1、Base Pass:应用一个逐像素的方向光、所有的逐顶点或SH的灯光;

          2、Additional Pass:逐个渲染每个逐像素光照,每盏光一个pass。

      同一个场景中每个物体的这4个点光源不一样,并且这4个point光是按照pixel优先的顺序选择的,如下图所示,场景中有很多点光源,但影响每个物体的四盏点光源会根据位置来自动选择:

    (3)Deferred Lighting:
      提供最好的光影效果,建议在有很多realtime lights的时候使用,它对硬件有一些要求。
      light数量没有限制,且所有light都per-pixel计算。
      原理:第一步准备N个与屏幕同大小的纹理作为渲染缓冲区,接下来向这个纹理渲染东西,一般用FBO,渲染的时候,把每个象素最终的法线值、位置、纹理信息分别渲染到这N个纹理中。
           第二步进行光照/渲染计算,将把之前得到的纹理中的值作为光照计算的输入值来计算光照。
      不支持Deffered Lighting的shader会自动使用Forward Rendering Path。
      优点:计算光照的计算量与场景复杂程度完全无关(三角形再多也不要紧),只与第一次渲染的像素数量和第二次渲染的光源数量成正比。这样,就可以在有限的硬件资源里使用大量的光源。避免多次(超过1次)渲染同一个像素。
           因为和场景复杂度无关,所以小的point light和spot light的开销都是很小的。
      缺点:1、无法使用基于硬件的抗锯齿,因为每个象素都独立计算;
         2、同时渲染多个纹理,显存压力很大;
          3、没法处理半透明,半透明物体只能提出来单独渲染一次(使用Forward Rendering);
          4、不支持MeshRender的Receive Shadows选项(只支持选中值),culling mask选项只有有限的支持(最多4个culling mask,那么意味着layer mask必须至少包含all layers - 4个layer)。

      实现细节:
        1、base pass:几个屏幕大小的buffer,分别包含depth、normals、specular power信息;
        2、lighting pass:在屏幕空间计算光照(所以开销和场景复杂度无关)并存在一张lighting buffer里,只能使用Blinn-Phong的光照模式。
        3、final pass:生成最终的渲染画面,物体再次被渲染,根据lighting信息、结合color textures和任何ambient/emissive lighting。

      至少需要Shader Model3.0,2004年之后出的显卡基本上都支持延迟渲染。

     (4)渲染路径和Pass的Tag

      Pass的LightMode Tag定义了其在渲染管线中的作用。

        Pass
        {
            Tags { "LightMode " = "ForwardBase"}
            ...
        }

      Deferred Lighting,使用PrepassBase和PrepassFinal的Pass;  

      Forward Lighting,使用ForwardBase和ForwardAdd的Pass;

        只有ForwardAdd没有ForwardBase时,ForwardAdd不会执行,被忽略。没有平行像素光,ForwardBase输出黑色,ForwardAdd会执行。

      Vertex Lit,使用Vertex、VertexLMRGB和VertexLM的Pass;

        Vertex:无lightmap,应用所有的vertex lights;

        VertexLMRGB:物体应用lightmap,lightmap为RGBM编码的PC和console平台;

        VertexLM:物体应用lightmap,lightmap为double-LDR编码的mobile平台。

        以上3种LightMode同时只会执行一种。

      在任何渲染路径中,渲染阴影是都会使用ShadowCaster和ShadowCollector的Pass。

      Always表示总是渲染,并且不应用光照。

      默认的LightMode为Always,非法的LightMode值,也当做Asways处理。

     测试渲染路径的shader:

    Shader "James/Other/TestRenderMode_All" 
    {
        Properties 
        {
            _MainTex ("Base (RGB)", 2D) = "white" {}
        }
        SubShader 
        {
            Tags { "RenderType"="Opaque" }
            LOD 200
            Blend One One
            
            /// 延迟渲染部分.begin
            CGPROGRAM
            #pragma surface surf MyDeferred
    
            sampler2D _MainTex;
    
            struct Input 
            {
                float2 uv_MainTex;
            };
            
            inline fixed4 LightingMyDeferred_PrePass (SurfaceOutput s, half4 light)
            {
                fixed4 c;
                c.rgb = s.Albedo * light.rgb;
                c.a = s.Alpha;
                return c;
            }
    
            void surf (Input IN, inout SurfaceOutput o) 
            {
                o.Albedo = float3(1, 0, 0);
            }
            ENDCG
            /// 延迟渲染部分.end
            
            /// 前向渲染部分.begin
            pass
            {
                Tags{"LightMode" = "ForwardBase"}
                Blend one one
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                #include "Lighting.cginc"
                
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float4 color : COLOR;
                };
                
                v2f vert(appdata_base v)
                {
                    v2f o;
                    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                    o.color = float4(0, 1, 0, 1);
                    return o;
                }
                
                float4 frag(v2f i) : COLOR
                {
                    return i.color;
                }
                
                ENDCG
            }
            /// 前向渲染部分.end
            
            /// 顶点渲染部分.begin
            pass
            {
                Tags{"LightMode" = "Vertex"}
                Blend one one
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                #include "Lighting.cginc"
                
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float4 color : COLOR;
                };
                
                v2f vert(appdata_base v)
                {
                    v2f o;
                    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                    o.color = float4(0, 0, 1, 1);
                    return o;
                }
                
                float4 frag(v2f i) : COLOR
                {
                    return i.color;
                }
                
                ENDCG
            }
            /// 顶点渲染部分.end
            
        } 
        FallBack "Diffuse"
    }

      上面的代码中,不同的渲染路径会输出不同的颜色,而具体哪个pass生效会根据unity的render path的设置来判断。

  • 相关阅读:
    Python将文件夹下的文件名写入excel方便统计
    Python利用openpyxl带格式统计数据(2)- 处理mysql数据
    Python利用openpyxl带格式统计数据(1)- 处理excel数据
    spfa 算法(队列优化的Bellman-Ford算法)
    bellman_ford算法(边数限制的最短路,边权可能为负)
    堆优化dijkstra
    朴素dijkstra
    1547. 切棍子的最小成本(区间dp)
    1546. 和为目标值的最大数目不重叠非空子数组数目(前缀和+dp)
    32场双周赛(模拟,模拟,前缀和加状态压缩)
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/4622751.html
Copyright © 2011-2022 走看看