CustomLighting.hlsl 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #ifndef CUSTOM_LIGHTING_INCLUDED
  2. #define CUSTOM_LIGHTING_INCLUDED
  3. // @Cyanilux | https://github.com/Cyanilux/URP_ShaderGraphCustomLighting
  4. // Note this version of the package assumes v12+ due to usage of "Branch on Input Connection" node
  5. // For older versions, see branches on github repo!
  6. //------------------------------------------------------------------------------------------------------
  7. // Main Light
  8. //------------------------------------------------------------------------------------------------------
  9. /*
  10. - Obtains the Direction, Color and Distance Atten for the Main Light.
  11. - (DistanceAtten is either 0 or 1 for directional light, depending if the light is in the culling mask or not)
  12. - If you want shadow attenutation, see MainLightShadows_float, or use MainLightFull_float instead
  13. */
  14. void MainLight_float (out float3 Direction, out float3 Color, out float DistanceAtten){
  15. #ifdef SHADERGRAPH_PREVIEW
  16. Direction = normalize(float3(1,1,-0.4));
  17. Color = float4(1,1,1,1);
  18. DistanceAtten = 1;
  19. #else
  20. Light mainLight = GetMainLight();
  21. Direction = mainLight.direction;
  22. Color = mainLight.color;
  23. DistanceAtten = mainLight.distanceAttenuation;
  24. #endif
  25. }
  26. //------------------------------------------------------------------------------------------------------
  27. // Main Light Layer Test
  28. //------------------------------------------------------------------------------------------------------
  29. #ifndef SHADERGRAPH_PREVIEW
  30. #if UNITY_VERSION < 202220
  31. /*
  32. GetMeshRenderingLayer() is only available in 2022.2+
  33. Previous versions need to use GetMeshRenderingLightLayer()
  34. */
  35. uint GetMeshRenderingLayer(){
  36. return GetMeshRenderingLightLayer();
  37. }
  38. #endif
  39. #endif
  40. /*
  41. - Tests whether the Main Light Layer Mask appears in the Rendering Layers from renderer
  42. - (Used to support Light Layers, pass your shading from Main Light into this)
  43. - To work in an Unlit Graph, requires keywords :
  44. - Boolean Keyword, Global Multi-Compile "_LIGHT_LAYERS"
  45. */
  46. void MainLightLayer_float(float3 Shading, out float3 Out){
  47. #ifdef SHADERGRAPH_PREVIEW
  48. Out = Shading;
  49. #else
  50. Out = 0;
  51. uint meshRenderingLayers = GetMeshRenderingLayer();
  52. #ifdef _LIGHT_LAYERS
  53. if (IsMatchingLightLayer(GetMainLight().layerMask, meshRenderingLayers))
  54. #endif
  55. {
  56. Out = Shading;
  57. }
  58. #endif
  59. }
  60. /*
  61. - Obtains the Light Cookie assigned to the Main Light
  62. - (For usage, You'd want to Multiply the result with your Light Colour)
  63. - To work in an Unlit Graph, requires keywords :
  64. - Boolean Keyword, Global Multi-Compile "_LIGHT_COOKIES"
  65. */
  66. void MainLightCookie_float(float3 WorldPos, out float3 Cookie){
  67. Cookie = 1;
  68. #if defined(_LIGHT_COOKIES)
  69. Cookie = SampleMainLightCookie(WorldPos);
  70. #endif
  71. }
  72. //------------------------------------------------------------------------------------------------------
  73. // Main Light Shadows
  74. //------------------------------------------------------------------------------------------------------
  75. /*
  76. - This undef (un-define) is required to prevent the "invalid subscript 'shadowCoord'" error,
  77. which occurs when _MAIN_LIGHT_SHADOWS is used with 1/No Shadow Cascades with the Unlit Graph.
  78. - It's not required for the PBR/Lit graph, so I'm using the SHADERPASS_FORWARD to ignore it for that pass
  79. */
  80. #ifndef SHADERGRAPH_PREVIEW
  81. #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl"
  82. #if (SHADERPASS != SHADERPASS_FORWARD)
  83. #undef REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR
  84. #endif
  85. #endif
  86. /*
  87. - Samples the Shadowmap for the Main Light, based on the World Position passed in. (Position node)
  88. - For shadows to work in the Unlit Graph, the following keywords must be defined in the blackboard :
  89. - Enum Keyword, Global Multi-Compile "_MAIN_LIGHT", with entries :
  90. - "SHADOWS"
  91. - "SHADOWS_CASCADE"
  92. - "SHADOWS_SCREEN"
  93. - Boolean Keyword, Global Multi-Compile "_SHADOWS_SOFT"
  94. - For a PBR/Lit Graph, these keywords are already handled for you.
  95. */
  96. void MainLightShadows_float (float3 WorldPos, half4 Shadowmask, out float ShadowAtten){
  97. #ifdef SHADERGRAPH_PREVIEW
  98. ShadowAtten = 1;
  99. #else
  100. #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
  101. float4 shadowCoord = ComputeScreenPos(TransformWorldToHClip(WorldPos));
  102. #else
  103. float4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
  104. #endif
  105. ShadowAtten = MainLightShadow(shadowCoord, WorldPos, Shadowmask, _MainLightOcclusionProbes);
  106. #endif
  107. }
  108. void MainLightShadows_float (float3 WorldPos, out float ShadowAtten){
  109. MainLightShadows_float(WorldPos, half4(1,1,1,1), ShadowAtten);
  110. }
  111. //------------------------------------------------------------------------------------------------------
  112. // Shadowmask (v10+)
  113. //------------------------------------------------------------------------------------------------------
  114. /*
  115. - Used to support "Shadowmask" mode in Lighting window.
  116. - Should be sampled once in graph, then input into the Main Light Shadows and/or Additional Light subgraphs/functions.
  117. - To work in an Unlit Graph, likely requires keywords :
  118. - Boolean Keyword, Global Multi-Compile "SHADOWS_SHADOWMASK"
  119. - Boolean Keyword, Global Multi-Compile "LIGHTMAP_SHADOW_MIXING"
  120. - (also LIGHTMAP_ON, but I believe Shader Graph is already defining this one)
  121. */
  122. void Shadowmask_half (float2 lightmapUV, out half4 Shadowmask){
  123. #ifdef SHADERGRAPH_PREVIEW
  124. Shadowmask = half4(1,1,1,1);
  125. #else
  126. OUTPUT_LIGHTMAP_UV(lightmapUV, unity_LightmapST, lightmapUV);
  127. Shadowmask = SAMPLE_SHADOWMASK(lightmapUV);
  128. #endif
  129. }
  130. //------------------------------------------------------------------------------------------------------
  131. // Ambient Lighting
  132. //------------------------------------------------------------------------------------------------------
  133. /*
  134. - Uses "SampleSH", the spherical harmonic stuff that ambient lighting / light probes uses.
  135. - Will likely be used in the fragment, so will be per-pixel.
  136. - Alternatively could use the Baked GI node, as it'll also handle this for you.
  137. - Could also use the Ambient node, would be cheaper but the result won't automatically adapt based on the Environmental Lighting Source (Lighting tab).
  138. */
  139. void AmbientSampleSH_float (float3 WorldNormal, out float3 Ambient){
  140. #ifdef SHADERGRAPH_PREVIEW
  141. Ambient = float3(0.1, 0.1, 0.1); // Default ambient colour for previews
  142. #else
  143. Ambient = SampleSH(WorldNormal);
  144. #endif
  145. }
  146. //------------------------------------------------------------------------------------------------------
  147. // Subtractive Baked GI
  148. //------------------------------------------------------------------------------------------------------
  149. /*
  150. - Used to support "Subtractive" mode in Lighting window.
  151. - To work in an Unlit Graph, likely requires keywords :
  152. - Boolean Keyword, Global Multi-Compile "LIGHTMAP_SHADOW_MIXING"
  153. - (also LIGHTMAP_ON, but I believe Shader Graph is already defining this one)
  154. */
  155. void SubtractiveGI_float (float ShadowAtten, float3 normalWS, float3 bakedGI, out half3 result){
  156. #ifdef SHADERGRAPH_PREVIEW
  157. result = half3(1,1,1);
  158. #else
  159. Light mainLight = GetMainLight();
  160. mainLight.shadowAttenuation = ShadowAtten;
  161. MixRealtimeAndBakedGI(mainLight, normalWS, bakedGI);
  162. result = bakedGI;
  163. #endif
  164. }
  165. //------------------------------------------------------------------------------------------------------
  166. // Mix Fog
  167. //------------------------------------------------------------------------------------------------------
  168. /*
  169. - Adds fog to the colour, based on the Fog settings in the Lighting tab.
  170. - Note : Not required for v12, can use Lerp instead. See "Mix Fog" SubGraph
  171. */
  172. void MixFog_float (float3 Colour, float Fog, out float3 Out){
  173. #ifdef SHADERGRAPH_PREVIEW
  174. Out = Colour;
  175. #else
  176. Out = MixFog(Colour, Fog);
  177. #endif
  178. }
  179. //------------------------------------------------------------------------------------------------------
  180. // Default Additional Lights
  181. //------------------------------------------------------------------------------------------------------
  182. /*
  183. - Handles additional lights (e.g. additional directional, point, spotlights)
  184. - For custom lighting, you may want to duplicate this and swap the LightingLambert / LightingSpecular functions out. See Toon Example below!
  185. - To work in the Unlit Graph, the following keywords must be defined in the blackboard :
  186. - Boolean Keyword, Global Multi-Compile "_ADDITIONAL_LIGHT_SHADOWS"
  187. - Boolean Keyword, Global Multi-Compile "_ADDITIONAL_LIGHTS"
  188. - To support Forward+ path,
  189. - Boolean Keyword, Global Multi-Compile "_FORWARD_PLUS" (2022.2+)
  190. */
  191. void AdditionalLights_float(float3 SpecColor, float Smoothness, float3 WorldPosition, float3 WorldNormal, float3 WorldView, half4 Shadowmask,
  192. out float3 Diffuse, out float3 Specular) {
  193. float3 diffuseColor = 0;
  194. float3 specularColor = 0;
  195. #ifndef SHADERGRAPH_PREVIEW
  196. Smoothness = exp2(10 * Smoothness + 1);
  197. uint pixelLightCount = GetAdditionalLightsCount();
  198. uint meshRenderingLayers = GetMeshRenderingLayer();
  199. #if USE_FORWARD_PLUS
  200. for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++) {
  201. FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
  202. Light light = GetAdditionalLight(lightIndex, WorldPosition, Shadowmask);
  203. #ifdef _LIGHT_LAYERS
  204. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  205. #endif
  206. {
  207. // Blinn-Phong
  208. float3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
  209. diffuseColor += LightingLambert(attenuatedLightColor, light.direction, WorldNormal);
  210. specularColor += LightingSpecular(attenuatedLightColor, light.direction, WorldNormal, WorldView, float4(SpecColor, 0), Smoothness);
  211. }
  212. }
  213. #endif
  214. // For Foward+ the LIGHT_LOOP_BEGIN macro will use inputData.normalizedScreenSpaceUV, inputData.positionWS, so create that:
  215. InputData inputData = (InputData)0;
  216. float4 screenPos = ComputeScreenPos(TransformWorldToHClip(WorldPosition));
  217. inputData.normalizedScreenSpaceUV = screenPos.xy / screenPos.w;
  218. inputData.positionWS = WorldPosition;
  219. LIGHT_LOOP_BEGIN(pixelLightCount)
  220. Light light = GetAdditionalLight(lightIndex, WorldPosition, Shadowmask);
  221. #ifdef _LIGHT_LAYERS
  222. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  223. #endif
  224. {
  225. // Blinn-Phong
  226. float3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
  227. diffuseColor += LightingLambert(attenuatedLightColor, light.direction, WorldNormal);
  228. specularColor += LightingSpecular(attenuatedLightColor, light.direction, WorldNormal, WorldView, float4(SpecColor, 0), Smoothness);
  229. }
  230. LIGHT_LOOP_END
  231. #endif
  232. Diffuse = diffuseColor;
  233. Specular = specularColor;
  234. }
  235. // For backwards compatibility (before Shadowmask was introduced)
  236. void AdditionalLights_float(float3 SpecColor, float Smoothness, float3 WorldPosition, float3 WorldNormal, float3 WorldView,
  237. out float3 Diffuse, out float3 Specular) {
  238. AdditionalLights_float(SpecColor, Smoothness, WorldPosition, WorldNormal, WorldView, half4(1,1,1,1), Diffuse, Specular);
  239. }
  240. //------------------------------------------------------------------------------------------------------
  241. // Additional Lights Toon Example
  242. //------------------------------------------------------------------------------------------------------
  243. /*
  244. - Calculates light attenuation values to produce multiple bands for a toon effect. See AdditionalLightsToon function below
  245. */
  246. #ifndef SHADERGRAPH_PREVIEW
  247. float ToonAttenuation(int lightIndex, float3 positionWS, float pointBands, float spotBands){
  248. #if !USE_FORWARD_PLUS
  249. lightIndex = GetPerObjectLightIndex(lightIndex);
  250. #endif
  251. #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
  252. float4 lightPositionWS = _AdditionalLightsBuffer[lightIndex].position;
  253. half4 spotDirection = _AdditionalLightsBuffer[lightIndex].spotDirection;
  254. half4 distanceAndSpotAttenuation = _AdditionalLightsBuffer[lightIndex].attenuation;
  255. #else
  256. float4 lightPositionWS = _AdditionalLightsPosition[lightIndex];
  257. half4 spotDirection = _AdditionalLightsSpotDir[lightIndex];
  258. half4 distanceAndSpotAttenuation = _AdditionalLightsAttenuation[lightIndex];
  259. #endif
  260. // Point
  261. float3 lightVector = lightPositionWS.xyz - positionWS * lightPositionWS.w;
  262. float distanceSqr = max(dot(lightVector, lightVector), HALF_MIN);
  263. float range = rsqrt(distanceAndSpotAttenuation.x);
  264. float dist = sqrt(distanceSqr) / range;
  265. // Spot
  266. half3 lightDirection = half3(lightVector * rsqrt(distanceSqr));
  267. half SdotL = dot(spotDirection.xyz, lightDirection);
  268. half spotAtten = saturate(SdotL * distanceAndSpotAttenuation.z + distanceAndSpotAttenuation.w);
  269. spotAtten *= spotAtten;
  270. float maskSpotToRange = step(dist, 1);
  271. // Atten
  272. bool isSpot = (distanceAndSpotAttenuation.z > 0);
  273. return isSpot ?
  274. //step(0.01, spotAtten) : // cheaper if you just want "1" band for spot lights
  275. (floor(spotAtten * spotBands) / spotBands) * maskSpotToRange :
  276. saturate(1.0 - floor(dist * pointBands) / pointBands);
  277. }
  278. #endif
  279. /*
  280. - Handles additional lights (e.g. point, spotlights) with banded toon effect
  281. - For shadows to work in the Unlit Graph, the following keywords must be defined in the blackboard :
  282. - Boolean Keyword, Global Multi-Compile "_ADDITIONAL_LIGHT_SHADOWS"
  283. - Boolean Keyword, Global Multi-Compile "_ADDITIONAL_LIGHTS" (required to prevent the one above from being stripped from builds)
  284. - For a PBR/Lit Graph, these keywords are already handled for you.
  285. */
  286. void AdditionalLightsToon_float(float3 SpecColor, float Smoothness, float3 WorldPosition, float3 WorldNormal, float3 WorldView, half4 Shadowmask,
  287. float PointLightBands, float SpotLightBands,
  288. out float3 Diffuse, out float3 Specular) {
  289. float3 diffuseColor = 0;
  290. float3 specularColor = 0;
  291. #ifndef SHADERGRAPH_PREVIEW
  292. Smoothness = exp2(10 * Smoothness + 1);
  293. uint pixelLightCount = GetAdditionalLightsCount();
  294. uint meshRenderingLayers = GetMeshRenderingLayer();
  295. #if USE_FORWARD_PLUS
  296. for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++) {
  297. FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
  298. Light light = GetAdditionalLight(lightIndex, WorldPosition, Shadowmask);
  299. #ifdef _LIGHT_LAYERS
  300. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  301. #endif
  302. {
  303. if (PointLightBands <= 1 && SpotLightBands <= 1){
  304. // Solid colour lights
  305. diffuseColor += light.color * step(0.0001, light.distanceAttenuation * light.shadowAttenuation);
  306. }else{
  307. // Multiple bands
  308. diffuseColor += light.color * light.shadowAttenuation * ToonAttenuation(lightIndex, WorldPosition, PointLightBands, SpotLightBands);
  309. }
  310. }
  311. }
  312. #endif
  313. // For Foward+ the LIGHT_LOOP_BEGIN macro will use inputData.normalizedScreenSpaceUV, inputData.positionWS, so create that:
  314. InputData inputData = (InputData)0;
  315. float4 screenPos = ComputeScreenPos(TransformWorldToHClip(WorldPosition));
  316. inputData.normalizedScreenSpaceUV = screenPos.xy / screenPos.w;
  317. inputData.positionWS = WorldPosition;
  318. LIGHT_LOOP_BEGIN(pixelLightCount)
  319. Light light = GetAdditionalLight(lightIndex, WorldPosition, Shadowmask);
  320. #ifdef _LIGHT_LAYERS
  321. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  322. #endif
  323. {
  324. if (PointLightBands <= 1 && SpotLightBands <= 1){
  325. // Solid colour lights
  326. diffuseColor += light.color * step(0.0001, light.distanceAttenuation * light.shadowAttenuation);
  327. }else{
  328. // Multiple bands
  329. diffuseColor += light.color * light.shadowAttenuation * ToonAttenuation(lightIndex, WorldPosition, PointLightBands, SpotLightBands);
  330. }
  331. }
  332. LIGHT_LOOP_END
  333. #endif
  334. /*
  335. #ifndef SHADERGRAPH_PREVIEW
  336. Smoothness = exp2(10 * Smoothness + 1);
  337. WorldNormal = normalize(WorldNormal);
  338. WorldView = SafeNormalize(WorldView);
  339. int pixelLightCount = GetAdditionalLightsCount();
  340. for (int i = 0; i < pixelLightCount; ++i) {
  341. Light light = GetAdditionalLight(i, WorldPosition, Shadowmask);
  342. // DIFFUSE
  343. if (PointLightBands <= 1 && SpotLightBands <= 1){
  344. // Solid colour lights
  345. diffuseColor += light.color * step(0.0001, light.distanceAttenuation * light.shadowAttenuation);
  346. }else{
  347. // Multiple bands :
  348. diffuseColor += light.color * light.shadowAttenuation * ToonAttenuation(i, WorldPosition, PointLightBands, SpotLightBands);
  349. }
  350. }
  351. #endif
  352. */
  353. Diffuse = diffuseColor;
  354. Specular = specularColor;
  355. // Didn't really like the look of specular lighting in the toon shader here, so just keeping it at 0
  356. }
  357. // For backwards compatibility (before Shadowmask was introduced)
  358. void AdditionalLightsToon_float(float3 SpecColor, float Smoothness, float3 WorldPosition, float3 WorldNormal, float3 WorldView,
  359. float PointLightBands, float SpotLightBands,
  360. out float3 Diffuse, out float3 Specular) {
  361. AdditionalLightsToon_float(SpecColor, Smoothness, WorldPosition, WorldNormal, WorldView, half4(1,1,1,1),
  362. PointLightBands, SpotLightBands,Diffuse, Specular);
  363. }
  364. //------------------------------------------------------------------------------------------------------
  365. // Additional Lights Zelda
  366. //------------------------------------------------------------------------------------------------------
  367. void AdditionaLightZelda_float(float3 WorldPosition, float3 WorldNormal, float3 WorldView, half4 Shadowmask, float LightStep,
  368. out float LightMask, out float3 LightColor, out float3 Specular) {
  369. float lightMask = 0;
  370. float3 lightColor = 0;
  371. float3 specularColor = 0;
  372. #ifndef SHADERGRAPH_PREVIEW
  373. uint pixelLightCount = GetAdditionalLightsCount();
  374. uint meshRenderingLayers = GetMeshRenderingLayer();
  375. //TODO: Fix the Forward Plus block
  376. #if USE_FORWARD_PLUS
  377. for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++) {
  378. FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
  379. Light light = GetAdditionalLight(0, WorldPosition, Shadowmask);
  380. #ifdef _LIGHT_LAYERS
  381. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  382. #endif
  383. {
  384. float adjustedContribution = step(LightStep, dot(light.direction, WorldNormal));
  385. lightMask = step(0.001, light.distanceAttenuation) * adjustedContribution; //this distance-based step function makes the light full brightness within its range/gizmo
  386. lightColor = light.color;
  387. }
  388. }
  389. #endif
  390. // For Foward+ the LIGHT_LOOP_BEGIN macro will use inputData.normalizedScreenSpaceUV, inputData.positionWS, so create that:
  391. InputData inputData = (InputData)0;
  392. float4 screenPos = ComputeScreenPos(TransformWorldToHClip(WorldPosition));
  393. inputData.normalizedScreenSpaceUV = screenPos.xy / screenPos.w;
  394. inputData.positionWS = WorldPosition;
  395. LIGHT_LOOP_BEGIN(min(1, pixelLightCount))
  396. Light light = GetAdditionalLight(0, WorldPosition, Shadowmask);
  397. #ifdef _LIGHT_LAYERS
  398. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  399. #endif
  400. {
  401. float adjustedContribution = step(LightStep, dot(light.direction, WorldNormal));
  402. lightMask = step(0.001, light.distanceAttenuation) * adjustedContribution; //this distance-based step function makes the light full brightness within its range/gizmo
  403. lightColor = light.color;
  404. }
  405. LIGHT_LOOP_END
  406. #endif
  407. LightColor = lightColor;
  408. LightMask = lightMask;
  409. Specular = specularColor;
  410. }
  411. // For backwards compatibility (before Shadowmask was introduced)
  412. void AdditionaLightZelda_float(float3 WorldPosition, float3 WorldNormal, float3 WorldView, float LightStep,
  413. out float LightMask, out float3 LightColor, out float3 Specular)
  414. {
  415. AdditionaLightZelda_float(WorldPosition, WorldNormal, WorldView, half4(1,1,1,1), LightStep,
  416. LightMask, LightColor, Specular);
  417. }
  418. #endif // CUSTOM_LIGHTING_INCLUDED