SpriteVertexLighting.cginc 15 KB

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