Unity LightMap Unlit Shader解读

使用场景:只使用lightmap,不考虑实时光照。

首先我们来看一下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
        }
    }    
}
}


其实这里比较难理解的是这里的LightMode,对照官方文档

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.

然后关于 VertexLMRGBM和VertexLMM编码的lightmap贴图的解码,我们可以参考一下UnityCG.cginc,这里和上面shader是相对应的

// 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
}

参考:

http://docs.unity3d.com/Manual/SL-RenderPipeline.html

http://docs.unity3d.com/Manual/SL-PassTags.html

http://docs.unity3d.com/Manual/RenderingPaths.html

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页