UnityShader实例07:在shader调用unity内置lightmap和light Probes
2015-07-09 11:37
597 查看
在shader调用unity内置lightmap和Light Probes
在编写unity shader的时候,有时候会有需求,希望写的shader能支持unity内置lightmap或者light probe (灯光探测器)。如果是用surface 编写的话,这些自然不用考虑,unity会自动编译支持,但如果是用vert&frag编写shader,这些需要自己添加相关代码调用了 。
unity内置lightmap的调用
为了使unity内置数据和各种宏定义(如本文的LIGHTMAP_OFF)起作用,需要添加#pragma指令:
在unity5.0之前的版本需要声明一下两个内置参数,unity5.0的话就不需要这两句了:
Lightmap是使用模型的uv2 ,因此接下来在顶点输入结构体里声明uv2:
在另一个顶点结构里面定义用来接收uv2的uv值:
在vert函数里面给uvLM赋值:
然后frag函数里对lightmap贴图采样并叠加给主颜色:
VF版本代码01:
VF版本代码01效果:
unity内置Light
Probes的调用
在shader中我们是通过unity定义的half3 ShadeSH9(half4 normal)来调用Light Probes的,Light Probes照明使用的是一种叫球谐光照(Sphere Harmonic)的模拟,简称SH,因此在ShadeSH9函数需要一个世界坐标中的Normal来决定物体表面的光照。
首先我们在顶点输出结构定义一个参数SHLighting:
然后在顶点函数里为它赋值:
VF版本代码02:
VF版本代码02效果
在编写unity shader的时候,有时候会有需求,希望写的shader能支持unity内置lightmap或者light probe (灯光探测器)。如果是用surface 编写的话,这些自然不用考虑,unity会自动编译支持,但如果是用vert&frag编写shader,这些需要自己添加相关代码调用了 。
unity内置lightmap的调用
为了使unity内置数据和各种宏定义(如本文的LIGHTMAP_OFF)起作用,需要添加#pragma指令:
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
在unity5.0之前的版本需要声明一下两个内置参数,unity5.0的话就不需要这两句了:
half4 unity_LightmapST; sampler2D unity_Lightmap;
Lightmap是使用模型的uv2 ,因此接下来在顶点输入结构体里声明uv2:
float2 texcoord1 : TEXCOORD1;
在另一个顶点结构里面定义用来接收uv2的uv值:
#ifndef LIGHTMAP_OFF half2 uvLM : TEXCOORD4; #endif
在vert函数里面给uvLM赋值:
#ifndef LIGHTMAP_OFF o.uvLM = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif
然后frag函数里对lightmap贴图采样并叠加给主颜色:
#ifndef LIGHTMAP_OFF fixed3 lm = DecodeLightmap (UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy)); col.rgb*=lm; #endif在上面的代码中使用了DecodeLightmap解码unity的内置光照贴图,这是因为Unity烘焙的LightMap是32bit的HDR图,在桌面端,光照贴图的编码为RGBM,而在移动端,大部分情况下,光照贴图的编码为double-LDR,因此需要针对不同平台提供不同的编码方式。DecodeLightmap作用就在这里,它可以针对不同的平台对光照贴图进行解码
VF版本代码01:
Shader "PengLu/Unlit/TextureLM" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 100
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
#ifndef LIGHTMAP_OFF
half2 uvLM : TEXCOORD1;
#endif
UNITY_FOG_COORDS(1)
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
#ifndef LIGHTMAP_OFF o.uvLM = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
UNITY_APPLY_FOG(i.fogCoord, col);
UNITY_OPAQUE_ALPHA(col.a);
#ifndef LIGHTMAP_OFF fixed3 lm = DecodeLightmap (UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy)); col.rgb*=lm; #endif
return col;
}
ENDCG
}
}
}
VF版本代码01效果:
unity内置Light
Probes的调用
在shader中我们是通过unity定义的half3 ShadeSH9(half4 normal)来调用Light Probes的,Light Probes照明使用的是一种叫球谐光照(Sphere Harmonic)的模拟,简称SH,因此在ShadeSH9函数需要一个世界坐标中的Normal来决定物体表面的光照。
首先我们在顶点输出结构定义一个参数SHLighting:
fixed3 SHLighting : COLOR;
然后在顶点函数里为它赋值:
float3 worldNormal = mul((float3x3)_Object2World, v.normal);//获得世界坐标中的normal o.SHLighting= ShadeSH9(float4(worldNormal,1)) ;
VF版本代码02:
Shader "PengLu/Unlit/TextureLM" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _SHLightingScale("LightProbe influence scale",float) = 1 } SubShader { Tags { "Queue"="Geometry""LightMode"="ForwardBase""RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog #include "UnityCG.cginc" struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; fixed3 SHLighting : COLOR; UNITY_FOG_COORDS(1) }; sampler2D _MainTex; float4 _MainTex_ST; float _SHLightingScale; v2f vert (appdata_base v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldNormal = mul((float3x3)_Object2World, v.normal); o.SHLighting= ShadeSH9(float4(worldNormal,1)) ; UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.texcoord); col.rgb*=i.SHLighting; UNITY_APPLY_FOG(i.fogCoord, col); UNITY_OPAQUE_ALPHA(col.a); return col*_SHLightingScale; } ENDCG } } }
VF版本代码02效果
相关文章推荐
- Unity中的Path对应各平台中的Path
- unity与wpf, winform双向交互的方法
- C#开发Unity游戏教程之Unity中方法的参数
- Unity3D游戏开发之SQLite让数据库开发更简单
- C#开发Unity游戏教程之Unity中方法的参数
- Unity Time类详解
- Unity4.x升级5.0出现的32位dll问题
- 在mac上构建Jenkins+unity3d+xcode发布流程
- Unity中NullReferenceException: (null) UnityEditor.SerializedObject..ctor (UnityEngine.Object[] 问题
- unity调用Android通过编译 java jar包出现问题解决和简单支付流程
- Unity 脚步 事件函数 的执行顺序
- android Unity3D 修改加强
- Unable to execute dex:multiple dex files define Lcom/unity3d/player/nativeloader
- unity双面材质攻略
- VMware 安装Ubuntu 12.04后启用虚拟机的unity mode模式
- unity3d相机跟随物体平滑移动(C#代码)
- unity3d在android下的真机测试<转载>
- unity鼠标拖动三维物体
- C#开发Unity游戏教程之游戏对象的行为逻辑方法
- Unity 3D MonoBehaviour Mono行为