Unity 的“Vertex Lit Rendering path“中 shader Pass 的注意事项
2013-06-19 23:06
274 查看
"MADFINGER/Environment/Unlit (Supports Lightmap)"是 ShadowGun 示例中最简单的 shader 了,如下:
在 Unity 中每一个 Pass 都会使得对象渲染一次,一般来讲 VertexLit 的 shader 只有一个 Pass,里面都是些简单状态设置和纹理混合,相当于 dx 的 .fx 文件。那么以上的 shader 中出现了3个不同的 Pass,是渲染3遍吗?
答案是否,请看官方的另一个说明:Unity's Rendering Pipeline, 文章最后一段写到(重点看红色粗体部分):
Unity 在使用 Vertex lit 模式时无法在内部自动分别处理使用了光照图的对象和未使用的,所以需要作者自己显式的针对 Vertex, VertexLMRGBM, VertexLMM 这三个 LightMode 的 PassTag 分别写一个 Pass,以便适应没有光照图,以及使用了光照图但编码不同的情况。
在 UnityCG.cginc 中的 DecodeLightmap 里包含了上述的两种光照图解码:
参照这个代码就能知道第一个 shader 中后两个 Pass 的算法和这个函数是对应的。
// 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.Vertexpass is used for non-lightmapped objects. All lights are rendered at once, using a fixed function OpenGL/Direct3D lighting model (Blinn-Phong)
VertexLMRGBMpass 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.
VertexLMMpass 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 的算法和这个函数是对应的。
相关文章推荐
- Unity顶点光照路径细节(Vertex Lit Rendering Path Details)
- Unity渲染路径 Rendering Paths_3_Vertex Lit 顶点光照
- 在程序中用new ClassPathXmlApplicationContext()的注意事项
- unity-----------------------------关于WheelCollider设置或小车运动的注意事项
- Unity插件之Tower Defence ToolKit (TDTK) 使用心得教程(一)---下载安装TDTK和NGUI及注意事项
- Unity的Android的SDK导入注意事项
- Unity Prime31 IAP 插件的导入注意事项
- unity, 播放循环背景音乐注意事项
- Unity_DOTween动画的学习(六)_From()用法理解和注意事项
- server.context-path不是默认的时候的注意事项
- ServletContext.getRealPath() 使用方法及注意事项
- IOC unity的配置文件注意事项
- Unity旧延迟光照渲染路径( Legacy Deferred Lighting Rendering Path)
- 在程序中用new ClassPathXmlApplicationContext()的注意事项
- import-module的注意事项与NDK_MODULE_PATH的配置
- Microsoft Unity 使用注意事项
- Unity AnimatorController注意事项
- Unity-Shader之法线贴图使用注意事项
- 3D max模型导入unity 3D中注意事项
- Unity调用c++动态链接库注意事项