多光源 MultipleLight

使用2个Pass增加光照效果;

第一个Pass是基础光源,一般是第一个平行光;Tags{"LightMode" = "ForwardBase"}

第二个光源是增加的光源,一般是点光源;Tags{"LightMode" = "ForwardAdd"} Blend One One

混合:Blend

 
这里例如我们给一个模型贴一个材质,那么在某个点计算出来颜色值称为源,而该点之前累积的颜色值,叫目标。
 
语法
Blend SrcFactor DstFactor  SrcFactor是源系数,DstFactor是目标系数
最终颜色 = (Shader计算出的点颜色值 * 源系数)+(点累积颜色 * 目标系数)
 
属性(往SrcFactor,DstFactor 上填的值)
one                          1
zero                         0
SrcColor                         源的RGB值,例如(0.5,0.4,1)
SrcAlpha                         源的A值, 例如0.6
DstColor                   混合目标的RGB值例如(0.5,0.4,1)
DstAlpha                         混合目标的A值例如0.6
OneMinusSrcColor          (1,1,1) - SrcColor
OneMinusSrcAlpha          1- SrcAlpha
OneMinusDstColor          (1,1,1) - DstColor
OneMinusDstAlpha          1- DstAlpha

我们在Pass中计算光源时,需要注意,是平行光还是点光源:

 1                 float3 lightDirection; 
 2                 float atten; 
 3 
 4                 if(_WorldSpaceLightPos0.w==0.0)//平行光
 5                 {
 6                     atten = 1.0;
 7                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
 8                 }
 9                 else
10                 {
11                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
12                     float distance = length(fragmentToLightSource);
13                     atten  = 1.0/distance;
14                     lightDirection = normalize(fragmentToLightSource);
15                 }

源代码:

  1 Shader "JQM/MultipleLight"
  2 {
  3     Properties
  4     {
  5         _Color("Color", color) = (1.0,1.0,1.0,1.0)
  6         _SpecColor("Specular Color", color) = (1.0,1.0,1.0,1.0)
  7         _Shininess("Shininess",float) = 10
  8         _RimColor("Rim Coloe Color", color) = (1.0,1.0,1.0,1.0)
  9         _RimPower("Rim Power",Range(0.1,10.0)) = 3.0
 10 
 11     }
 12     SubShader{
 13         Pass{
 14             
 15             Tags { "LightMode" = "ForwardBase"}
 16 
 17             CGPROGRAM
 18             #pragma vertex vert
 19             #pragma fragment frag
 20 
 21             //使用自定义变量
 22             uniform float4 _Color;
 23             uniform float4 _SpecColor;
 24             uniform float4 _RimColor;
 25             uniform float _Shininess;
 26             uniform float _RimPower;
 27 
 28             //使用Unity定义的变量
 29             uniform float4 _LightColor0;
 30 
 31             struct vertexInput{
 32                 float4 vertex:POSITION;
 33                 float3 normal:NORMAL;
 34             };
 35 
 36             struct vertexOutput{
 37                 float4 pos:SV_POSITION;
 38                 float4 posWorld:TEXCOORD0;
 39                 float3 normalDir:TEXCOORD1;
 40             };
 41 
 42             //顶点程序
 43             vertexOutput vert(vertexInput v)
 44             {
 45                 vertexOutput o;
 46                 o.posWorld = mul(_Object2World, v.vertex);
 47                 o.normalDir =  normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
 48                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 49                 return o;
 50             }
 51 
 52             //片段程序
 53             float4 frag(vertexOutput i):COLOR
 54             {
 55 
 56                 float3 normalDirection = i.normalDir;
 57                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
 58                 float3 lightDirection; 
 59                 float atten; 
 60 
 61                 if(_WorldSpaceLightPos0.w==0.0)//平行光
 62                 {
 63                     atten = 1.0;
 64                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
 65                 }
 66                 else
 67                 {
 68                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
 69                     float distance = length(fragmentToLightSource);
 70                     atten  = 1.0/distance;
 71                     lightDirection = normalize(fragmentToLightSource);
 72                 }
 73                 
 74                 //灯光
 75                 float3 diffuseReflection = atten * _LightColor0.xyz *  saturate( dot(normalDirection,lightDirection));
 76                 float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
 77                 
 78                 //Rim Light
 79                 float rim= 1-dot(normalize(viewDirection),normalDirection);
 80                 float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
 81                 float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
 82                 return float4(lightFinal*_Color.xyz,1.0);
 83             }
 84 
 85             ENDCG
 86         }
 87 
 88         Pass{
 89             
 90             Tags { "LightMode" = "ForwardAdd"}
 91             Blend  One One
 92 
 93             CGPROGRAM
 94             #pragma vertex vert
 95             #pragma fragment frag
 96 
 97             //使用自定义变量
 98             uniform float4 _Color;
 99             uniform float4 _SpecColor;
100             uniform float4 _RimColor;
101             uniform float _Shininess;
102             uniform float _RimPower;
103 
104             //使用Unity定义的变量
105             uniform float4 _LightColor0;
106 
107             struct vertexInput{
108                 float4 vertex:POSITION;
109                 float3 normal:NORMAL;
110             };
111 
112             struct vertexOutput{
113                 float4 pos:SV_POSITION;
114                 float4 posWorld:TEXCOORD0;
115                 float3 normalDir:TEXCOORD1;
116             };
117 
118             //顶点程序
119             vertexOutput vert(vertexInput v)
120             {
121                 vertexOutput o;
122                 o.posWorld = mul(_Object2World, v.vertex);
123                 o.normalDir =  normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
124                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
125                 return o;
126             }
127 
128             //片段程序
129             float4 frag(vertexOutput i):COLOR
130             {
131 
132                 float3 normalDirection = i.normalDir;
133                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
134                 float3 lightDirection; 
135                 float atten; 
136 
137                 if(_WorldSpaceLightPos0.w==0.0)//平行光
138                 {
139                     atten = 1.0;
140                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
141                 }
142                 else
143                 {
144                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
145                     float distance = length(fragmentToLightSource);
146                     atten = 1.0/distance;
147                     lightDirection = normalize(fragmentToLightSource);
148                 }
149                 
150                 //灯光
151                 float3 diffuseReflection = atten * _LightColor0.xyz *  saturate( dot(normalDirection,lightDirection));
152                 float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
153                 
154                 //Rim Light
155                 float rim= 1-dot(normalize(viewDirection),normalDirection);
156                 float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
157                 float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
158                 return float4(lightFinal*_Color.xyz,1.0);
159             }
160 
161             ENDCG
162         }
163     }
164     
165 }
原文地址:https://www.cnblogs.com/jqm304775992/p/4896522.html