博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lightmaping
阅读量:6933 次
发布时间:2019-06-27

本文共 9865 字,大约阅读时间需要 32 分钟。

一、基本知识点

  1、Baked Only:不会传入shader,只有烘焙时才有用,也就是_LightColor0等这种变量不会表示一个Baked Only Light(前提是场景有lightmap,如果没有烘培,baked only的参数没有意义);
  (1)烘焙完以后,再将Realtime Only改为Baked Only,还是会传入shader;
  (2)Baked的Light,在烘焙完后,手动改为Realtime Only,还是会传入shader。
  2、Realtime Only:只有实时光照,不参与烘焙过程;
  3、Auto:Unity自己判断你是烘焙的还是实时的。
二、渲染路径相关
  1、VertexLit渲染路径下的光照贴图:
  Vertex Pass和VertexLM* Pass,同时只会执行一种:
  当场景没有lightmap时,会执行Vertex Pass;
  当场景有lightmap时,烘培过的static物体会执行VertexLM* Pass,其它物体执行Vertex Pass。
  注意:Always Pass还是会一直执行。
  Unity默认材质,如果被烘培了,就不再受实时光照影响,也就是说Realtime Only light都直接被忽略。
  可以自己写shader来实现lightmap静态物体,同时有实时光照的效果。
  自发光材质,也能烘焙出光影效果,但需要标记为static,可以按照制定规范自己编写自发光材质。
  2、Forward渲染路径下的光照贴图:
  a.对于Unity bulit-in的shader,物体可以同时接受lightmap和realtime光照效果,
  实时影响烘焙物体的light的属性:pixel、支持RealTime。
  被烘培锅的光源不再对烘焙过的物体产生照明。
  b.自定义shader

  #pragma multi_compile_fwdbase  #ifndef LIGHTMAP_OFF  sampler2D unity_LightMap;  float4 unity_LightMapST;  #endif  // lightmap的颜色  #ifndef LIGHTMAP_OFF  float3 c_lm = DecodeLightmap(tex2D(unity_LightMap, i.uv2));  c_tex.rgb = c_tex.rgb * c_lm;  #endif

  3、Deferred渲染路径下的光照贴图:

  双光照贴图默认只在Deferred模式下使用。
  在Forward渲染路径下,可以使用Surface Shader来使用双光照贴图:

#pragma surface surf Lambert dualforward

三、光照贴图模式:

  1、Single Lightmaps
  单光照贴图只生成Far光照图。
  烘焙场景时凹凸信息会丢失。
  2、Dual Lightmaps
  Far光照图:完全的GI光照;
  Near光照图:只包含Indirect照明。
  影响参数:QualitySettings.shadowDistance,物体到相机的距离。
  当距离>shadowDistance时,渐变到Far贴图,没有实时光照;
  当距离<shadowDistance时,渐变到Near贴图,也就是Indirect光照贴图+实时光照。
  应用原理:根据distance在Far和Near两组光照贴图之间混合。
  优点:既可以让我们的场景有GI照明的真实感,又可以拥有动态光源的变化。
  双光照贴图可以很好地支持Specular和凹凸贴图。
  3、Directional Lightmaps
  color光照图:和单光照贴图的完全一样,只包含颜色信息;
  scale光照图:存储灯光的方向信息。
  方向不是指方向光,而是说烘焙出的贴图会保存灯光的方向信息。
四、在shader中使用lightmap的数据:
  1、要使用vs/ps的shader,不使用surface shader
  2、访问lightmap数据的变量:

sampler2D unity_Lightmap;float4 unity_LightmapST;

  3、unity_LightmapST在规范上来说有一个命名失误,将_ST写成了ST,所以在计算uv的时候不能这样:

  o.uv1 = TRANSFORM_TEX(v.texcoord1.xy, unity_Lightmap);
  因为TRANSFORM_TEX的定义为:
  #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
  那么对于lightmap需要这样做:
  o.uv1 = i.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  4、根据DecodeLightmap函数来解析lightmap颜色值,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    return (8.0 * color.a) * color.rgb;    #endif  }

  那么获得Lightmap颜色的代码为:

  half4 lm = tex2D(unity_Lightmap, i.lmuv.xy);  fixed3 lightmapColor = DecodeLightmap(lm);

 五、shader示例

  VertexLit渲染路径下支持Lightmap:

Shader "James/VP Shader/LightMap-VertexLit"{    Properties     {        _MainTex ("Base (RGB)", 2D) = "white" {}        _addColor ("addColor", Color) = (1, 1, 1, 1)    }    SubShader     {        Pass        {                Tags { "LightMode" = "Vertex"}            LOD 200                        CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            sampler2D _MainTex;            float4 _MainTex_ST;            struct v2f             {                float4 pos: POSITION;                float3 normal: TEXCOORD0;                float2 uv: TEXCOORD1;                float4 lightingColor : TEXCOORD2;            };                        v2f vert(appdata_base data)            {                v2f o;                o.lightingColor.rgb = ShadeVertexLights(data.vertex, data.normal);                o.lightingColor.a = 1;                o.pos = mul(UNITY_MATRIX_MVP, data.vertex);                o.uv =     TRANSFORM_TEX(data.texcoord, _MainTex);                o.normal = data.normal;                return o;            }                        float4 frag(v2f data) : COLOR            {                fixed4 texColor = tex2D(_MainTex, data.uv);                return texColor * data.lightingColor;                // return float4(0, 1, 0, 1);            }            ENDCG        }                Pass        {                Tags { "LightMode" = "VertexLMRGBM"}            LOD 200                        CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            float4 _addColor;                        sampler2D _MainTex;            float4 _MainTex_ST;            sampler2D unity_Lightmap;            float4 unity_LightmapST;            struct v2f             {                float4 pos: POSITION;                float3 normal: TEXCOORD0;                float2 uv_tex: TEXCOORD1;                float2 uv_lm: TEXCOORD2;                // 实时光照成分                float3 lightingColor : TEXCOORD3;            };                        v2f vert(appdata_full data)            {                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, data.vertex);                o.uv_tex =     TRANSFORM_TEX(data.texcoord, _MainTex);                o.uv_lm  = data.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;                o.normal = data.normal;                o.lightingColor = ShadeVertexLights(data.vertex, data.normal);                return o;            }                        float4 frag(v2f data) : COLOR            {                // 纹理颜色                fixed4 texColor = tex2D(_MainTex, data.uv_tex);                // 解码的lightmap颜色                fixed4 lm = tex2D(unity_Lightmap, data.uv_lm);                fixed3 lmColor = DecodeLightmap(lm);                // 纹理色 * 光照色                texColor.rgb = texColor.rgb * lmColor;                return texColor * fixed4(data.lightingColor, 1);            }            ENDCG        }    }     FallBack "Diffuse"}

  Forward渲染路径下支持Lightmap:

Shader "James/VP Shader/LightMap-ForwardLM"{    Properties     {        _MainTex ("Base (RGB)", 2D) = "white" {}        _Color ("Base Color", Color) = (1, 1, 1, 1)    }    SubShader    {        Pass        {                Tags { "LightMode" = "ForwardBase"}            LOD 200                        CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #pragma multi_compile_fwdbase            #include "UnityCG.cginc"            #include "Lighting.cginc"            uniform float4 _Color;                        sampler2D _MainTex;            float4 _MainTex_ST;                        #ifndef LIGHTMAP_OFF            sampler2D unity_Lightmap;            float4 unity_LightmapST;            #endif            struct vertOut             {                float4 pos: POSITION;                float4 color: COLOR;                float3 litDir: TEXCOORD0;                float3 worldN: TEXCOORD1;                float2 uv: TEXCOORD2;                                #ifndef LIGHTMAP_OFF                float2 uv2: TEXCOORD3;                #endif            };                        vertOut vert(appdata_full v)            {                // 世界坐标                float4 worldV = mul(_Object2World, v.vertex);                // 世界法线                // float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL).xyz;                    float3 worldN = mul(_Object2World, float4(SCALED_NORMAL, 0)).xyz;                float3 c = Shade4PointLights(unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,                                              unity_LightColor[0], unity_LightColor[1], unity_LightColor[2], unity_LightColor[3],                                             unity_4LightAtten0, worldV.xyz, worldN);                            vertOut o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                o.litDir = WorldSpaceLightDir(v.vertex);                o.worldN = worldN;                // 4盏点光源的光照                o.color = float4(c, 1.0) * _Color;                o.uv = TRANSFORM_TEX(v.texcoord.xy, _MainTex);                                #ifndef LIGHTMAP_OFF                o.uv2 = (v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw);                #endif                                return o;            }            float4 frag(vertOut i) : COLOR            {                // 1个主光的光照                float4 c = max(0.0, dot(i.worldN, normalize(i.litDir))) * _LightColor0 * _Color;                // 纹理颜色                float4 c_tex = tex2D(_MainTex, i.uv);                                #ifndef LIGHTMAP_OFF                float3 c_lm = DecodeLightmap(tex2D(unity_Lightmap, i.uv2));                c_tex.rgb *= c_lm;                #endif                return c + c_tex + i.color;            }            ENDCG        }                Pass        {                Tags { "LightMode" = "ForwardAdd"}            LOD 200            Blend One One                         CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            #include "Lighting.cginc"                    uniform float4 _Color;            struct vertOut            {                float4 pos : SV_POSITION;                float3 litDir : TEXCOORD0;                float3 worldN : TEXCOORD1;                float atten : TEXCOORD2;            };            vertOut vert(appdata_base v)            {                float3 worldN = mul(_Object2World, float4(SCALED_NORMAL, 0)).xyz;                                vertOut o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                o.litDir = WorldSpaceLightDir(v.vertex);                o.worldN = worldN;                float dist = length(o.litDir);                // 根据_WorldSpaceLightPos0.w来判断是方向光还是点光源                o.atten = 1 / (1 + dist * dist * _WorldSpaceLightPos0.w);                return o;            }                        float4 frag(vertOut i) : COLOR            {                float4 c = _LightColor0 * _Color * max(0.0, dot(i.worldN, normalize(i.litDir))) * i.atten;                return c;            }            ENDCG        }    }     FallBack "Diffuse"}

 

转载地址:http://hpgjl.baihongyu.com/

你可能感兴趣的文章
『互联网架构』软件架构-spring源码之spring结构概述
查看>>
CentOS7搭建LNMP--编译安装
查看>>
JVM上的响应式流 — Reactor简介
查看>>
看板中的WIP限制思想
查看>>
构造函数(constructor)与原型链(prototype)关系
查看>>
The project you were looking for could not be found
查看>>
华为云携手秒拍,云+AI助力短视频加速发展
查看>>
罗辑思维在全链路压测方面的实践和工作笔记
查看>>
人工智能深度学习Caffe框架介绍,优秀的深度学习架构
查看>>
如何将qlv格式倚天屠龙记转换为MP4格式
查看>>
最全的MAC端截图工具推荐,寻找适合自己的截图工具
查看>>
使用 nginx 同域名下部署多个 vue 项目,并使用反向代理
查看>>
Python基本数据类型之元组
查看>>
LeetCode-数组-删除有序数组重复元素
查看>>
我所理解的原型&原型链
查看>>
工作三年,我要如何提升Java技术 | 粉丝提问
查看>>
JavaScript 如何使用闭包
查看>>
React 教程:快速上手指南
查看>>
6 个理由,让我不顾一切撑腰 Python!
查看>>
[ 一起学React系列 -- 11 ] React-Router4 (1)
查看>>