多光源 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 }