zoukankan      html  css  js  c++  java
  • Unity 的“Vertex Lit Rendering path“中 shader Pass 的注意事项

          "MADFINGER/Environment/Unlit (Supports Lightmap)"是 ShadowGun 示例中最简单的 shader 了,如下:

    // Unlit shader. Simplest possible textured shader.
    // - SUPPORTS lightmap
    // - no lighting
    // - no per-material color
    
    Shader "MADFINGER/Environment/Unlit (Supports Lightmap)" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Color ("HACK: temporary to fix lightmap bouncing light (will be fixed in RC1)", Color) = (1,1,1,1)
    }
    
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 100
        
        // Non-lightmapped
        Pass {
            Tags { "LightMode" = "Vertex" }
            Lighting Off
            SetTexture [_MainTex] { combine texture } 
        }
        
        // Lightmapped, encoded as dLDR
        Pass {
            Tags { "LightMode" = "VertexLM" }
    
            Lighting Off
            BindChannels {
                Bind "Vertex", vertex
                Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
                Bind "texcoord", texcoord1 // main uses 1st uv
            }
            
            SetTexture [unity_Lightmap] {
                matrix [unity_LightmapMatrix]
                combine texture
            }
            SetTexture [_MainTex] {
                combine texture * previous DOUBLE, texture * primary
            }
        }
        
        // Lightmapped, encoded as RGBM
        Pass {
            Tags { "LightMode" = "VertexLMRGBM" }
            
            Lighting Off
            BindChannels {
                Bind "Vertex", vertex
                Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
                Bind "texcoord", texcoord1 // main uses 1st uv
            }
            
            SetTexture [unity_Lightmap] {
                matrix [unity_LightmapMatrix]
                combine texture * texture alpha DOUBLE
            }
            SetTexture [_MainTex] {
                combine texture * previous QUAD, texture * primary
            }
        }    
    }
    }

      在 Unity 中每一个 Pass 都会使得对象渲染一次,一般来讲 VertexLit 的 shader 只有一个 Pass,里面都是些简单状态设置和纹理混合,相当于 dx 的 .fx 文件。那么以上的 shader 中出现了3个不同的 Pass,是渲染3遍吗?

      答案是否,请看官方的另一个说明:Unity's Rendering Pipeline, 文章最后一段写到(重点看红色粗体部分):

    Vertex Lit Rendering path

    Since vertex lighting is most often used on platforms that do not support programmable shaders, Unity can't create multiple shader permutations internally to handle lightmapped vs. non-lightmapped cases. So to handle lightmapped and non-lightmapped objects, multiple passes have to be written explicitly.

    • Vertex pass is used for non-lightmapped objects. All lights are rendered at once, using a fixed function OpenGL/Direct3D lighting model (Blinn-Phong)
    • VertexLMRGBM pass is used for lightmapped objects, when lightmaps are RGBM encoded (this happens on most desktops and consoles). No realtime lighting is applied; pass is expected to combine textures with a lightmap.
    • VertexLMM pass is used for lightmapped objects, when lightmaps are double-LDR encoded (this happens on mobiles and old desktops). No realtime lighting is applied; pass is expected to combine textures with a lightmap.

      Unity 在使用 Vertex lit 模式时无法在内部自动分别处理使用了光照图的对象和未使用的,所以需要作者自己显式的针对 Vertex, VertexLMRGBM, VertexLMM 这三个 LightMode 的 PassTag 分别写一个 Pass,以便适应没有光照图,以及使用了光照图但编码不同的情况。

      在 UnityCG.cginc 中的 DecodeLightmap 里包含了上述的两种光照图解码:

    // Decodes lightmaps:
    // - doubleLDR encoded on GLES
    // - RGBM encoded with range [0;8] on other platforms using surface shaders
    inline fixed3 DecodeLightmap( fixed4 color )
    {
    #if defined(SHADER_API_GLES) && defined(SHADER_API_MOBILE)
        return 2.0 * color.rgb;
    #else
        // potentially faster to do the scalar multiplication
        // in parenthesis for scalar GPUs
        return (8.0 * color.a) * color.rgb;
    #endif
    }

      参照这个代码就能知道第一个 shader 中后两个 Pass 的算法和这个函数是对应的。

     
  • 相关阅读:
    使用EF进行简单的增删改查
    观察者模式(委托事件的小应用)
    lambda表达式和表达式树
    socket知识总结
    xml读写Demo
    winfrom DataGridView Demo
    6月26号.NET面试题(程序题部分)只要做懂这3道题肯定能脱离菜鸟称号!
    多线程与异步编程知识简单总结
    15年6月14号面试中没有回答出来的问题
    2020.5.15记一次阿里电话面试经历
  • 原文地址:https://www.cnblogs.com/yaukey/p/unity_vertexlit_shader_pass.html
Copyright © 2011-2022 走看看