SpriteVertexLighting.cginc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #ifndef SPRITE_VERTEX_LIGHTING_INCLUDED
  2. #define SPRITE_VERTEX_LIGHTING_INCLUDED
  3. #include "ShaderShared.cginc"
  4. #include "SpriteLighting.cginc"
  5. #include "SpriteSpecular.cginc"
  6. ////////////////////////////////////////
  7. // Defines
  8. //
  9. //Define to use spot lights (more expensive)
  10. #define SPOT_LIGHTS
  11. //Have to process lighting per pixel if using normal maps or a diffuse ramp or rim lighting or specular
  12. #if defined(_NORMALMAP) || defined(_DIFFUSE_RAMP) || defined(_RIM_LIGHTING) || defined(SPECULAR)
  13. #define PER_PIXEL_LIGHTING
  14. #endif
  15. //Turn off bump mapping and diffuse ramping on older shader models as they dont support needed number of outputs
  16. #if defined(PER_PIXEL_LIGHTING) && (SHADER_TARGET < 30)
  17. #undef PER_PIXEL_LIGHTING
  18. #undef _NORMALMAP
  19. #undef _DIFFUSE_RAMP
  20. #undef _RIM_LIGHTING
  21. #endif
  22. //In D3D9 only have a max of 9 TEXCOORD so can't have diffuse ramping or fog or rim lighting if processing lights per pixel
  23. #if defined(SHADER_API_D3D9) && defined(PER_PIXEL_LIGHTING)
  24. #if defined(_NORMALMAP)
  25. #undef _DIFFUSE_RAMP
  26. #undef _FOG
  27. #undef _RIM_LIGHTING
  28. #elif defined(_DIFFUSE_RAMP)
  29. #undef _FOG
  30. #undef _RIM_LIGHTING
  31. #elif defined(_RIM_LIGHTING)
  32. #undef _FOG
  33. #undef _DIFFUSE_RAMP
  34. #else
  35. #undef _DIFFUSE_RAMP
  36. #undef _RIM_LIGHTING
  37. #endif
  38. #endif
  39. #if defined(PER_PIXEL_LIGHTING)
  40. #if defined(_NORMALMAP) && defined(_DIFFUSE_RAMP)
  41. #define ATTENUATIONS TEXCOORD9
  42. #if defined(_RIM_LIGHTING)
  43. #define _POS_WORLD_INDEX TEXCOORD10
  44. #define _FOG_COORD_INDEX 11
  45. #else
  46. #define _FOG_COORD_INDEX 10
  47. #endif
  48. #elif defined(_NORMALMAP) != defined(_DIFFUSE_RAMP)
  49. #define ATTENUATIONS TEXCOORD8
  50. #if defined(_RIM_LIGHTING)
  51. #define _POS_WORLD_INDEX TEXCOORD9
  52. #define _FOG_COORD_INDEX 10
  53. #else
  54. #define _FOG_COORD_INDEX 9
  55. #endif
  56. #else //!_DIFFUSE_RAMP && !_NORMALMAP
  57. #if defined(_RIM_LIGHTING)
  58. #define _POS_WORLD_INDEX TEXCOORD8
  59. #define _FOG_COORD_INDEX 9
  60. #else
  61. #define _FOG_COORD_INDEX 8
  62. #endif
  63. #endif
  64. #else //!PER_PIXEL_LIGHTING
  65. #define _FOG_COORD_INDEX 2
  66. #endif
  67. ////////////////////////////////////////
  68. // Vertex output struct
  69. //
  70. struct VertexOutput
  71. {
  72. float4 pos : SV_POSITION;
  73. fixed4 color : COLOR;
  74. float3 texcoord : TEXCOORD0;
  75. #if defined(PER_PIXEL_LIGHTING)
  76. half4 VertexLightInfo0 : TEXCOORD1;
  77. half4 VertexLightInfo1 : TEXCOORD2;
  78. half4 VertexLightInfo2 : TEXCOORD3;
  79. half4 VertexLightInfo3 : TEXCOORD4;
  80. half4 VertexLightInfo4 : TEXCOORD5;
  81. #if defined(_NORMALMAP)
  82. half4 normalWorld : TEXCOORD6;
  83. half4 tangentWorld : TEXCOORD7;
  84. half4 binormalWorld : TEXCOORD8;
  85. #else
  86. half3 normalWorld : TEXCOORD6;
  87. half3 VertexLightInfo5 : TEXCOORD7;
  88. #endif
  89. #if defined(_DIFFUSE_RAMP)
  90. half4 LightAttenuations : ATTENUATIONS;
  91. #endif
  92. #if defined(_RIM_LIGHTING)
  93. float4 posWorld : _POS_WORLD_INDEX;
  94. #endif
  95. #else //!PER_PIXEL_LIGHTING
  96. half3 FullLighting : TEXCOORD1;
  97. #endif // !PER_PIXEL_LIGHTING
  98. #if defined(_FOG)
  99. UNITY_FOG_COORDS(_FOG_COORD_INDEX)
  100. #endif // _FOG
  101. UNITY_VERTEX_OUTPUT_STEREO
  102. };
  103. ////////////////////////////////////////
  104. // Light calculations
  105. //
  106. struct VertexLightInfo
  107. {
  108. half3 lightDirection;
  109. fixed3 lightColor;
  110. #if defined(_DIFFUSE_RAMP)
  111. float attenuation;
  112. #endif // _DIFFUSE_RAMP
  113. };
  114. inline VertexLightInfo getVertexLightAttenuatedInfo(int index, float3 viewPos)
  115. {
  116. VertexLightInfo lightInfo;
  117. //For directional lights unity_LightPosition.w is set to zero
  118. lightInfo.lightDirection = unity_LightPosition[index].xyz - viewPos.xyz * unity_LightPosition[index].w;
  119. float lengthSq = dot(lightInfo.lightDirection, lightInfo.lightDirection);
  120. // don't produce NaNs if some vertex position overlaps with the light
  121. lengthSq = max(lengthSq, 0.000001);
  122. lightInfo.lightDirection *= rsqrt(lengthSq);
  123. float attenuation = 1.0 / (1.0 + lengthSq * unity_LightAtten[index].z);
  124. #if defined(SPOT_LIGHTS)
  125. //Spot light attenuation - for non-spot lights unity_LightAtten.x is set to -1 and y is set to 1
  126. {
  127. float rho = max (0, dot(lightInfo.lightDirection, unity_SpotDirection[index].xyz));
  128. float spotAtt = (rho - unity_LightAtten[index].x) * unity_LightAtten[index].y;
  129. attenuation *= saturate(spotAtt);
  130. }
  131. #endif // SPOT_LIGHTS
  132. //If using a diffuse ramp texture then need to pass through the lights attenuation, otherwise premultiply the light color with it
  133. #if defined(_DIFFUSE_RAMP)
  134. lightInfo.lightColor = unity_LightColor[index].rgb;
  135. lightInfo.attenuation = attenuation;
  136. #else
  137. lightInfo.lightColor = unity_LightColor[index].rgb * attenuation;
  138. #endif // _DIFFUSE_RAMP
  139. return lightInfo;
  140. }
  141. //Magic constants used to tweak ambient to approximate pixel shader spherical harmonics
  142. static const fixed3 worldUp = fixed3(0, 1, 0);
  143. static const float skyGroundDotMul = 2.5;
  144. static const float minEquatorMix = 0.5;
  145. static const float equatorColorBlur = 0.33;
  146. fixed3 calculateAmbientLight(half3 normalWorld)
  147. {
  148. #if defined(_SPHERICAL_HARMONICS)
  149. float upDot = dot(normalWorld, worldUp);
  150. //Fade between a flat lerp from sky to ground and a 3 way lerp based on how bright the equator light is.
  151. //This simulates how directional lights get blurred using spherical harmonics
  152. //Work out color from ground and sky, ignoring equator
  153. float adjustedDot = upDot * skyGroundDotMul;
  154. fixed3 skyGroundColor = lerp(unity_AmbientGround, unity_AmbientSky, saturate((adjustedDot + 1.0) * 0.5));
  155. //Work out equator lights brightness
  156. float equatorBright = saturate(dot(unity_AmbientEquator.rgb, unity_AmbientEquator.rgb));
  157. //Blur equator color with sky and ground colors based on how bright it is.
  158. fixed3 equatorBlurredColor = lerp(unity_AmbientEquator, saturate(unity_AmbientEquator + unity_AmbientGround + unity_AmbientSky), equatorBright * equatorColorBlur);
  159. //Work out 3 way lerp inc equator light
  160. fixed3 equatorColor = lerp(equatorBlurredColor, unity_AmbientGround, -upDot) * step(upDot, 0) + lerp(equatorBlurredColor, unity_AmbientSky, upDot) * step(0, upDot);
  161. //Mix the two colors together based on how bright the equator light is
  162. return lerp(skyGroundColor, equatorColor, saturate(equatorBright + minEquatorMix));
  163. #else // !_SPHERICAL_HARMONICS
  164. //Flat ambient is just the sky color
  165. return unity_AmbientSky.rgb;
  166. #endif // !_SPHERICAL_HARMONICS
  167. }
  168. ////////////////////////////////////////
  169. // Light Packing Functions
  170. //
  171. #if defined(_DIFFUSE_RAMP)
  172. inline fixed3 calculateLightDiffuse(fixed3 lightColor, half3 viewNormal, half3 lightViewDir, float attenuation)
  173. {
  174. float angleDot = max(0, dot(viewNormal, lightViewDir));
  175. fixed3 lightDiffuse = calculateRampedDiffuse(lightColor, attenuation, angleDot);
  176. return lightDiffuse;
  177. }
  178. #else
  179. inline fixed3 calculateLightDiffuse(fixed3 attenuatedLightColor, half3 viewNormal, half3 lightViewDir)
  180. {
  181. float angleDot = max(0, dot(viewNormal, lightViewDir));
  182. fixed3 lightDiffuse = attenuatedLightColor * angleDot;
  183. return lightDiffuse;
  184. }
  185. #endif // _NORMALMAP
  186. #if defined(PER_PIXEL_LIGHTING)
  187. #define VERTEX_LIGHT_0_DIR VertexLightInfo0.xyz
  188. #define VERTEX_LIGHT_0_R VertexLightInfo4.x
  189. #define VERTEX_LIGHT_0_G VertexLightInfo4.y
  190. #define VERTEX_LIGHT_0_B VertexLightInfo4.z
  191. #define VERTEX_LIGHT_1_DIR VertexLightInfo1.xyz
  192. #define VERTEX_LIGHT_1_R VertexLightInfo0.w
  193. #define VERTEX_LIGHT_1_G VertexLightInfo1.w
  194. #define VERTEX_LIGHT_1_B VertexLightInfo2.w
  195. #define VERTEX_LIGHT_2_DIR VertexLightInfo2.xyz
  196. #define VERTEX_LIGHT_2_R VertexLightInfo3.w
  197. #define VERTEX_LIGHT_2_G VertexLightInfo4.w
  198. #define VERTEX_LIGHT_2_B texcoord.z
  199. #define VERTEX_LIGHT_3_DIR VertexLightInfo3.xyz
  200. #if defined(_NORMALMAP)
  201. #define VERTEX_LIGHT_3_R normalWorld.w
  202. #define VERTEX_LIGHT_3_G tangentWorld.w
  203. #define VERTEX_LIGHT_3_B binormalWorld.w
  204. #else
  205. #define VERTEX_LIGHT_3_R VertexLightInfo5.x
  206. #define VERTEX_LIGHT_3_G VertexLightInfo5.y
  207. #define VERTEX_LIGHT_3_B VertexLightInfo5.z
  208. #endif
  209. #if defined(_DIFFUSE_RAMP)
  210. #define LIGHT_DIFFUSE_ATTEN_0 LightAttenuations.x
  211. #define LIGHT_DIFFUSE_ATTEN_1 LightAttenuations.y
  212. #define LIGHT_DIFFUSE_ATTEN_2 LightAttenuations.z
  213. #define LIGHT_DIFFUSE_ATTEN_3 LightAttenuations.w
  214. #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo) \
  215. { \
  216. output.LIGHT_DIFFUSE_ATTEN_##index = lightInfo.attenuation; \
  217. }
  218. #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
  219. { \
  220. diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir, input.LIGHT_DIFFUSE_ATTEN_##index); \
  221. }
  222. #else
  223. #define PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo)
  224. #define ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
  225. { \
  226. diffuse += calculateLightDiffuse(lightColor, viewNormal, lightViewDir); \
  227. }
  228. #endif
  229. #define PACK_VERTEX_LIGHT(index, output, viewPos) \
  230. { \
  231. VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos); \
  232. output.VERTEX_LIGHT_##index##_DIR = lightInfo.lightDirection; \
  233. output.VERTEX_LIGHT_##index##_R = lightInfo.lightColor.r; \
  234. output.VERTEX_LIGHT_##index##_G = lightInfo.lightColor.g; \
  235. output.VERTEX_LIGHT_##index##_B = lightInfo.lightColor.b; \
  236. PACK_VERTEX_LIGHT_DIFFUSE(index, output, lightInfo); \
  237. }
  238. #define ADD_VERTEX_LIGHT(index, input, viewNormal, diffuse) \
  239. { \
  240. half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \
  241. fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \
  242. ADD_VERTEX_LIGHT_DIFFUSE(index, diffuse, input, lightColor, viewNormal, lightViewDir) \
  243. }
  244. #if defined(SPECULAR)
  245. #define ADD_VERTEX_LIGHT_SPEC(index, input, viewNormal, specData, combinedLightData, indirectDiffuse, indirectSpecular) \
  246. { \
  247. half3 lightViewDir = input.VERTEX_LIGHT_##index##_DIR; \
  248. fixed3 lightColor = fixed3(input.VERTEX_LIGHT_##index##_R, input.VERTEX_LIGHT_##index##_G, input.VERTEX_LIGHT_##index##_B); \
  249. SpecularLightData lightData = calculatePhysicsBasedSpecularLight(specData.specColor, specData.oneMinusReflectivity, specData.smoothness, viewNormal, fixed3(0,0,1), lightViewDir, lightColor, indirectDiffuse, indirectSpecular); \
  250. combinedLightData.lighting += lightData.lighting; \
  251. combinedLightData.specular += lightData.specular; \
  252. }
  253. #endif
  254. #else //!PER_PIXEL_LIGHTING
  255. ////////////////////////////////////////
  256. // Vertex Only Functions
  257. //
  258. inline fixed3 calculateLightDiffuse(int index, float3 viewPos, half3 viewNormal)
  259. {
  260. VertexLightInfo lightInfo = getVertexLightAttenuatedInfo(index, viewPos);
  261. float angleDot = max(0, dot(viewNormal, lightInfo.lightDirection));
  262. return lightInfo.lightColor * angleDot;
  263. }
  264. #endif // !PER_PIXEL_LIGHTING
  265. ////////////////////////////////////////
  266. // Vertex program
  267. //
  268. VertexOutput vert(VertexInput input)
  269. {
  270. VertexOutput output;
  271. UNITY_SETUP_INSTANCE_ID(input);
  272. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  273. output.pos = calculateLocalPos(input.vertex);
  274. output.color = calculateVertexColor(input.color);
  275. output.texcoord = float3(calculateTextureCoord(input.texcoord), 0);
  276. float3 viewPos = UnityObjectToViewPos(input.vertex); //float3 viewPos = mul(UNITY_MATRIX_MV, input.vertex); //
  277. #if defined(FIXED_NORMALS_BACKFACE_RENDERING) || defined(_RIM_LIGHTING)
  278. float4 powWorld = calculateWorldPos(input.vertex);
  279. #endif
  280. float backFaceSign = 1;
  281. #if defined(FIXED_NORMALS_BACKFACE_RENDERING)
  282. backFaceSign = calculateBackfacingSign(powWorld.xyz);
  283. #endif
  284. #if defined(PER_PIXEL_LIGHTING)
  285. #if defined(_RIM_LIGHTING)
  286. output.posWorld = powWorld;
  287. #endif
  288. PACK_VERTEX_LIGHT(0, output, viewPos)
  289. PACK_VERTEX_LIGHT(1, output, viewPos)
  290. PACK_VERTEX_LIGHT(2, output, viewPos)
  291. PACK_VERTEX_LIGHT(3, output, viewPos)
  292. output.normalWorld.xyz = calculateSpriteWorldNormal(input, backFaceSign);
  293. #if defined(_NORMALMAP)
  294. output.tangentWorld.xyz = calculateWorldTangent(input.tangent);
  295. output.binormalWorld.xyz = calculateSpriteWorldBinormal(input, output.normalWorld, output.tangentWorld, backFaceSign);
  296. #endif
  297. #else // !PER_PIXEL_LIGHTING
  298. //Just pack full lighting
  299. float3 viewNormal = calculateSpriteViewNormal(input, backFaceSign);
  300. //Get Ambient diffuse
  301. float3 normalWorld = calculateSpriteWorldNormal(input, backFaceSign);
  302. fixed3 ambient = calculateAmbientLight(normalWorld);
  303. fixed3 diffuse = calculateLightDiffuse(0, viewPos, viewNormal);
  304. diffuse += calculateLightDiffuse(1, viewPos, viewNormal);
  305. diffuse += calculateLightDiffuse(2, viewPos, viewNormal);
  306. diffuse += calculateLightDiffuse(3, viewPos, viewNormal);
  307. output.FullLighting = ambient + diffuse;
  308. #endif // !PER_PIXEL_LIGHTING
  309. #if defined(_FOG)
  310. UNITY_TRANSFER_FOG(output, output.pos);
  311. #endif // _FOG
  312. return output;
  313. }
  314. ////////////////////////////////////////
  315. // Fragment program
  316. //
  317. fixed4 frag(VertexOutput input) : SV_Target
  318. {
  319. fixed4 texureColor = calculateTexturePixel(input.texcoord.xy);
  320. RETURN_UNLIT_IF_ADDITIVE_SLOT(texureColor, input.color) // shall be called before ALPHA_CLIP
  321. ALPHA_CLIP(texureColor, input.color)
  322. #if defined(PER_PIXEL_LIGHTING)
  323. #if defined(_NORMALMAP)
  324. half3 normalWorld = calculateNormalFromBumpMap(input.texcoord.xy, input.tangentWorld.xyz, input.binormalWorld.xyz, input.normalWorld.xyz);
  325. #else
  326. half3 normalWorld = input.normalWorld.xyz;
  327. #endif
  328. //Get Ambient diffuse
  329. fixed3 ambient = calculateAmbientLight(normalWorld);
  330. half3 normalView = normalize(mul((float3x3)UNITY_MATRIX_V, normalWorld));
  331. #if defined(SPECULAR)
  332. SpecularCommonData specData = getSpecularData(input.texcoord.xy, texureColor, input.color);
  333. SpecularLightData combinedLightData = (SpecularLightData)0;
  334. ADD_VERTEX_LIGHT_SPEC(0, input, normalView, specData, combinedLightData, ambient, unity_IndirectSpecColor.rgb)
  335. ADD_VERTEX_LIGHT_SPEC(1, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
  336. ADD_VERTEX_LIGHT_SPEC(2, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
  337. ADD_VERTEX_LIGHT_SPEC(3, input, normalView, specData, combinedLightData, fixed3(0,0,0), fixed3(0,0,0))
  338. fixed4 pixel = calculateLitPixel(fixed4(specData.diffColor, specData.alpha), combinedLightData.lighting);
  339. pixel.rgb += combinedLightData.specular * specData.alpha;
  340. APPLY_EMISSION_SPECULAR(pixel, input.texcoord)
  341. #else
  342. //Find vertex light diffuse
  343. fixed3 diffuse = fixed3(0,0,0);
  344. //Add each vertex light to diffuse
  345. ADD_VERTEX_LIGHT(0, input, normalView, diffuse)
  346. ADD_VERTEX_LIGHT(1, input, normalView, diffuse)
  347. ADD_VERTEX_LIGHT(2, input, normalView, diffuse)
  348. ADD_VERTEX_LIGHT(3, input, normalView, diffuse)
  349. fixed3 lighting = ambient + diffuse;
  350. APPLY_EMISSION(lighting, input.texcoord.xy)
  351. fixed4 pixel = calculateLitPixel(texureColor, input.color, lighting);
  352. #endif
  353. #if defined(_RIM_LIGHTING)
  354. pixel.rgb = applyRimLighting(input.posWorld, normalWorld, pixel);
  355. #endif
  356. #else // !PER_PIXEL_LIGHTING
  357. APPLY_EMISSION(input.FullLighting, input.texcoord.xy)
  358. fixed4 pixel = calculateLitPixel(texureColor, input.color, input.FullLighting);
  359. #endif // !PER_PIXEL_LIGHTING
  360. COLORISE(pixel)
  361. APPLY_FOG(pixel, input)
  362. return pixel;
  363. }
  364. #endif // SPRITE_VERTEX_LIGHTING_INCLUDED