Surface Shaders 内置灯光模型(Build in lighting models)Lighting.cginc 和如何自定义灯光类型
2017-10-31 14:07
651 查看
//如果没有定义 LIGHTING_INCLUDED 的话 (这是"if not defined"的简写,是宏定义的一种,它是可以根据是否已经定义了一个变量来进行分支选择,) #ifndef LIGHTING_INCLUDED //使用 LIGHTING_INCLUDED #define LIGHTING_INCLUDED //引用 XXX #include "UnityLightingCommon.cginc" #include "UnityGBuffer.cginc" #include "UnityGlobalIllumination.cginc" //SurfaceOutput 结构体 struct SurfaceOutput { fixed3 Albedo; fixed3 Normal; fixed3 Emission; half Specular; fixed Gloss; fixed Alpha; }; #ifndef USING_DIRECTIONAL_LIGHT #if defined (DIRECTIONAL_COOKIE) || defined (DIRECTIONAL) #define USIN 4000 G_DIRECTIONAL_LIGHT #endif #endif //如果 满足后面这些条件,执行 define (UNITY_LIGHT_FUNCTION_APPLY_INDIRECT) #if defined(UNITY_SHOULD_SAMPLE_SH) || defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON) #define UNITY_LIGHT_FUNCTION_APPLY_INDIRECT #endif //声明 fixed4 UnityLambertLight inline fixed4 UnityLambertLight (SurfaceOutput s, UnityLight light) { fixed diff = max (0, dot (s.Normal, light.dir)); fixed4 c; c.rgb = s.Albedo * light.color * diff; c.a = s.Alpha; return c; } //声明 fixed4 LightingLambert inline fixed4 LightingLambert (SurfaceOutput s, UnityGI gi) { fixed4 c; c = UnityLambertLight (s, gi.light); #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT c.rgb += s.Albedo * gi.indirect.diffuse; #endif return c; } //声明 half4 LightingLambert_Deferred inline half4 LightingLambert_Deferred (SurfaceOutput s, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2) { UnityStandardData data; data.diffuseColor = s.Albedo; data.occlusion = 1; data.specularColor = 0; data.smoothness = 0; data.normalWorld = s.Normal; UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2); half4 emission = half4(s.Emission, 1); #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT emission.rgb += s.Albedo * gi.indirect.diffuse; #endif return emission; } //声明无类型的一个函数 LightingLambert_GI inline void LightingLambert_GI ( SurfaceOutput s, UnityGIInput data, inout UnityGI gi) { gi = UnityGlobalIllumination (data, 1.0, s.Normal); } //声明 LightingLambert_PrePass inline fixed4 LightingLambert_PrePass (SurfaceOutput s, half4 light) { fixed4 c; c.rgb = s.Albedo * light.rgb; c.a = s.Alpha; return c; } // NOTE: some intricacy in shader compiler on some GLES2.0 platforms (iOS) needs 'viewDir' & 'h' // to be mediump instead of lowp, otherwise specular highlight becomes too bright. inline fixed4 UnityBlinnPhongLight (SurfaceOutput s, half3 viewDir, UnityLight light) { half3 h = normalize (light.dir + viewDir); fixed diff = max (0, dot (s.Normal, light.dir)); float nh = max (0, dot (s.Normal, h)); float spec = pow (nh, s.Specular*128.0) * s.Gloss; fixed4 c; c.rgb = s.Albedo * light.color * diff + light.color * _SpecColor.rgb * spec; c.a = s.Alpha; return c; } inline fixed4 LightingBlinnPhong (SurfaceOutput s, half3 viewDir, UnityGI gi) { fixed4 c; c = UnityBlinnPhongLight (s, viewDir, gi.light); #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT c.rgb += s.Albedo * gi.indirect.diffuse; #endif return c; } inline half4 LightingBlinnPhong_Deferred (SurfaceOutput s, half3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2) { UnityStandardData data; data.diffuseColor = s.Albedo; data.occlusion = 1; // PI factor come from StandardBDRF (UnityStandardBRDF.cginc:351 for explanation) data.specularColor = _SpecColor.rgb * s.Gloss * (1/UNITY_PI); data.smoothness = s.Specular; data.normalWorld = s.Normal; UnityStandardDataToGbuffer(data, outGBuffer0, outGBuffer1, outGBuffer2); half4 emission = half4(s.Emission, 1); #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT emission.rgb += s.Albedo * gi.indirect.diffuse; #endif return emission; } inline void LightingBlinnPhong_GI ( SurfaceOutput s, UnityGIInput data, inout UnityGI gi) { gi = UnityGlobalIllumination (data, 1.0, s.Normal); } inline fixed4 LightingBlinnPhong_PrePass (SurfaceOutput s, half4 light) { fixed spec = light.a * s.Gloss; fixed4 c; c.rgb = (s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec); c.a = s.Alpha; return c; } #ifdef UNITY_CAN_COMPILE_TESSELLATION struct UnityTessellationFactors { float edge[3] : SV_TessFactor; float inside : SV_InsideTessFactor; }; #endif // UNITY_CAN_COMPILE_TESSELLATION // Deprecated, kept around for existing user shaders. #define UNITY_DIRBASIS \ const half3x3 unity_DirBasis = half3x3( \ half3( 0.81649658, 0.0, 0.57735027), \ half3(-0.40824830, 0.70710678, 0.57735027), \ half3(-0.40824830, -0.70710678, 0.57735027) \ ); // Deprecated, kept around for existing user shaders. Only sampling the flat lightmap now. half3 DirLightmapDiffuse(in half3x3 dirBasis, fixed4 color, fixed4 scale, half3 normal, bool surfFuncWritesNormal, out half3 scalePerBasisVector) { return DecodeLightmap (color); } #endif
自定义灯光类型(包含上文的语法):
Custom Lighting models in Surface Shaders
When writing Surface Shaders, you’re describing properties of a surface (albedo color, normal, …) and the lighting interaction is computed by aLighting Model. Built-in lighting models are Lambert (diffuse lighting) and
BlinnPhong (specular lighting).
Sometimes you might want to use a custom lighting model, and it is possible to do that in Surface Shaders. Lighting model is nothing more than a couple of Cg/HLSL functions that match some conventions. The built-in
Lambertand
BlinnPhongmodels are defined in
Lighting.cgincfile inside Unity ({unity install path}/Data/CGIncludes/Lighting.cginc on Windows,
/Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc on Mac).
Lighting Model declaration
Lighting model is a couple of regular functions with names starting withLighting. They can be declared anywhere in your shader file or one of included files. The functions are:
half4 Lighting<Name> (SurfaceOutput s, UnityGI gi);This is used in forward rendering path for light models that
are not view direction dependent (e.g. diffuse).
half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi);This is used in forward rendering path for light models that are view direction dependent.
half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal);This is used in deferred lighting path.
half4 Lighting<Name>_PrePass (SurfaceOutput s, half4 light);This is used in light prepass (legacy deferred) lighting path.
Note that you don’t need to declare all functions. A lighting model either uses view direction or it does not. Similarly, if the lighting model only works in forward, do not declare the
_Deferredor
_Prepassfunction. This way, all Shaders that use it compile to forward rendering only.
Custom GI
Similarly, customize the decoding lightmap data and probes by declaring the function below.half4 Lighting<Name>_GI (SurfaceOutput s, UnityGIInput data, inout UnityGI gi);
Note that to decode standard Unity lightmaps and SH probes, you can use the built-in
DecodeLightmap and ShadeSHPerPixel functions, as seen in
UnityGI_Base in the
UnityGlobalIllumination.cgincfile inside Unity ({unity install path}/Data/CGIncludes/UnityGlobalIllumination.cginc on Windows,
/Applications/Unity/Unity.app/Contents/CGIncludes/UnityGlobalIllumination.cginc on Mac).
Examples
Surface Shader Lighting Examples相关文章推荐
- Lambert漫反射.BLinnPhong及Phong模型 Unity自带的在Lighting.cginc里
- 自定义URDF机器人模型时,编译urdf文件时,提示Error: Error reading end tag. at line 72 in /build/urdfdom-UJ3kd6/urd
- How to Build an Economic Model in Your Spare Time (如何利用业余时间建立经济模型)
- Swift编程语言中如何实现自定义类型的for-in循环(基于Swift 2.2)
- PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
- 如何在客户端判断浏览器的类型(Detecting IE7+ in JavaScript)
- SP2010开发和VS2010专家"食谱"--第四章节—列表定义和内容类型(3)--使用对象模型创建自定义内容类型
- QT中如何在ComboBox中设置存放自定义类型
- Android中intent如何传递自定义数据类型
- ASP.NET 2.0: Add build-in paging feature to repeater/为repeater添加内置分页功能
- 实现自定义模型(Implementing Custom Models)
- MySQL存储过程和自定义函数、Navicat、创建存储过程和函数、调用存储过程和函数、三种方式、In和Out类型参数、
- 织梦自定义模型如何实现采集功能
- ADO.NET Entity Framework如何:通过每种类型一个表继承以定义模型(实体框架)
- 如何构建一个比较好的自定义异常处理模型?
- python-24-如何派生类内置不可变类型并修改其实例化行为?如何为创建大量实例节省内存?
- SP2010开发和VS2010专家"食谱"--第四章节—列表定义和内容类型(3)--使用对象模型创建自定义内容类型
- 如何实现WCF中的自定义集合类型传输
- 如何创建自定义的文件类型关联
- 《C++ Concurrency in Action》读书笔记四 c++内存模型和原子类型