Lighting.hlsl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #ifndef UNIVERSAL_LIGHTING_INCLUDED
  2. #define UNIVERSAL_LIGHTING_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
  8. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
  9. #if defined(LIGHTMAP_ON)
  10. #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index
  11. #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw;
  12. #define OUTPUT_SH(normalWS, OUT)
  13. #else
  14. #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index
  15. #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)
  16. #define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)
  17. #endif
  18. ///////////////////////////////////////////////////////////////////////////////
  19. // Lighting Functions //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)
  22. {
  23. half NdotL = saturate(dot(normal, lightDir));
  24. return lightColor * NdotL;
  25. }
  26. half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)
  27. {
  28. float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
  29. half NdotH = half(saturate(dot(normal, halfVec)));
  30. half modifier = pow(NdotH, smoothness);
  31. half3 specularReflection = specular.rgb * modifier;
  32. return lightColor * specularReflection;
  33. }
  34. half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat,
  35. half3 lightColor, half3 lightDirectionWS, half lightAttenuation,
  36. half3 normalWS, half3 viewDirectionWS,
  37. half clearCoatMask, bool specularHighlightsOff)
  38. {
  39. half NdotL = saturate(dot(normalWS, lightDirectionWS));
  40. half3 radiance = lightColor * (lightAttenuation * NdotL);
  41. half3 brdf = brdfData.diffuse;
  42. #ifndef _SPECULARHIGHLIGHTS_OFF
  43. [branch] if (!specularHighlightsOff)
  44. {
  45. brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);
  46. #if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
  47. // Clear coat evaluates the specular a second timw and has some common terms with the base specular.
  48. // We rely on the compiler to merge these and compute them only once.
  49. half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS);
  50. // Mix clear coat and base layer using khronos glTF recommended formula
  51. // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md
  52. // Use NoV for direct too instead of LoH as an optimization (NoV is light invariant).
  53. half NoV = saturate(dot(normalWS, viewDirectionWS));
  54. // Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization.
  55. // It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct)
  56. half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV);
  57. brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask;
  58. #endif // _CLEARCOAT
  59. }
  60. #endif // _SPECULARHIGHLIGHTS_OFF
  61. return brdf * radiance;
  62. }
  63. half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff)
  64. {
  65. return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff);
  66. }
  67. // Backwards compatibility
  68. half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS)
  69. {
  70. #ifdef _SPECULARHIGHLIGHTS_OFF
  71. bool specularHighlightsOff = true;
  72. #else
  73. bool specularHighlightsOff = false;
  74. #endif
  75. const BRDFData noClearCoat = (BRDFData)0;
  76. return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff);
  77. }
  78. half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS)
  79. {
  80. Light light;
  81. light.color = lightColor;
  82. light.direction = lightDirectionWS;
  83. light.distanceAttenuation = lightAttenuation;
  84. light.shadowAttenuation = 1;
  85. return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS);
  86. }
  87. half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff)
  88. {
  89. const BRDFData noClearCoat = (BRDFData)0;
  90. return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff);
  91. }
  92. half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff)
  93. {
  94. Light light;
  95. light.color = lightColor;
  96. light.direction = lightDirectionWS;
  97. light.distanceAttenuation = lightAttenuation;
  98. light.shadowAttenuation = 1;
  99. return LightingPhysicallyBased(brdfData, light, viewDirectionWS, specularHighlightsOff, specularHighlightsOff);
  100. }
  101. half3 VertexLighting(float3 positionWS, half3 normalWS)
  102. {
  103. half3 vertexLightColor = half3(0.0, 0.0, 0.0);
  104. #ifdef _ADDITIONAL_LIGHTS_VERTEX
  105. uint lightsCount = GetAdditionalLightsCount();
  106. LIGHT_LOOP_BEGIN(lightsCount)
  107. Light light = GetAdditionalLight(lightIndex, positionWS);
  108. half3 lightColor = light.color * light.distanceAttenuation;
  109. vertexLightColor += LightingLambert(lightColor, light.direction, normalWS);
  110. LIGHT_LOOP_END
  111. #endif
  112. return vertexLightColor;
  113. }
  114. struct LightingData
  115. {
  116. half3 giColor;
  117. half3 mainLightColor;
  118. half3 additionalLightsColor;
  119. half3 vertexLightingColor;
  120. half3 emissionColor;
  121. };
  122. half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
  123. {
  124. half3 lightingColor = 0;
  125. if (IsOnlyAOLightingFeatureEnabled())
  126. {
  127. return lightingData.giColor; // Contains white + AO
  128. }
  129. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
  130. {
  131. lightingColor += lightingData.giColor;
  132. }
  133. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
  134. {
  135. lightingColor += lightingData.mainLightColor;
  136. }
  137. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
  138. {
  139. lightingColor += lightingData.additionalLightsColor;
  140. }
  141. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
  142. {
  143. lightingColor += lightingData.vertexLightingColor;
  144. }
  145. lightingColor *= albedo;
  146. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
  147. {
  148. lightingColor += lightingData.emissionColor;
  149. }
  150. return lightingColor;
  151. }
  152. half4 CalculateFinalColor(LightingData lightingData, half alpha)
  153. {
  154. half3 finalColor = CalculateLightingColor(lightingData, 1);
  155. return half4(finalColor, alpha);
  156. }
  157. half4 CalculateFinalColor(LightingData lightingData, half3 albedo, half alpha, float fogCoord)
  158. {
  159. #if defined(_FOG_FRAGMENT)
  160. #if (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
  161. float viewZ = -fogCoord;
  162. float nearToFarZ = max(viewZ - _ProjectionParams.y, 0);
  163. half fogFactor = ComputeFogFactorZ0ToFar(nearToFarZ);
  164. #else
  165. half fogFactor = 0;
  166. #endif
  167. #else
  168. half fogFactor = fogCoord;
  169. #endif
  170. half3 lightingColor = CalculateLightingColor(lightingData, albedo);
  171. half3 finalColor = MixFog(lightingColor, fogFactor);
  172. return half4(finalColor, alpha);
  173. }
  174. LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
  175. {
  176. LightingData lightingData;
  177. lightingData.giColor = inputData.bakedGI;
  178. lightingData.emissionColor = surfaceData.emission;
  179. lightingData.vertexLightingColor = 0;
  180. lightingData.mainLightColor = 0;
  181. lightingData.additionalLightsColor = 0;
  182. return lightingData;
  183. }
  184. half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData)
  185. {
  186. half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
  187. half3 lightColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
  188. lightColor *= surfaceData.albedo;
  189. #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
  190. half smoothness = exp2(10 * surfaceData.smoothness + 1);
  191. lightColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness);
  192. #endif
  193. return lightColor;
  194. }
  195. ///////////////////////////////////////////////////////////////////////////////
  196. // Fragment Functions //
  197. // Used by ShaderGraph and others builtin renderers //
  198. ///////////////////////////////////////////////////////////////////////////////
  199. ////////////////////////////////////////////////////////////////////////////////
  200. /// PBR lighting...
  201. ////////////////////////////////////////////////////////////////////////////////
  202. half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData)
  203. {
  204. #if defined(_SPECULARHIGHLIGHTS_OFF)
  205. bool specularHighlightsOff = true;
  206. #else
  207. bool specularHighlightsOff = false;
  208. #endif
  209. BRDFData brdfData;
  210. // NOTE: can modify "surfaceData"...
  211. InitializeBRDFData(surfaceData, brdfData);
  212. #if defined(DEBUG_DISPLAY)
  213. half4 debugColor;
  214. if (CanDebugOverrideOutputColor(inputData, surfaceData, brdfData, debugColor))
  215. {
  216. return debugColor;
  217. }
  218. #endif
  219. // Clear-coat calculation...
  220. BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData);
  221. half4 shadowMask = CalculateShadowMask(inputData);
  222. AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
  223. uint meshRenderingLayers = GetMeshRenderingLightLayer();
  224. Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
  225. // NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
  226. MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);
  227. LightingData lightingData = CreateLightingData(inputData, surfaceData);
  228. lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask,
  229. inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
  230. inputData.normalWS, inputData.viewDirectionWS);
  231. if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
  232. {
  233. lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat,
  234. mainLight,
  235. inputData.normalWS, inputData.viewDirectionWS,
  236. surfaceData.clearCoatMask, specularHighlightsOff);
  237. }
  238. #if defined(_ADDITIONAL_LIGHTS)
  239. uint pixelLightCount = GetAdditionalLightsCount();
  240. #if USE_CLUSTERED_LIGHTING
  241. for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
  242. {
  243. Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
  244. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  245. {
  246. lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
  247. inputData.normalWS, inputData.viewDirectionWS,
  248. surfaceData.clearCoatMask, specularHighlightsOff);
  249. }
  250. }
  251. #endif
  252. LIGHT_LOOP_BEGIN(pixelLightCount)
  253. Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
  254. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  255. {
  256. lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light,
  257. inputData.normalWS, inputData.viewDirectionWS,
  258. surfaceData.clearCoatMask, specularHighlightsOff);
  259. }
  260. LIGHT_LOOP_END
  261. #endif
  262. #if defined(_ADDITIONAL_LIGHTS_VERTEX)
  263. lightingData.vertexLightingColor += inputData.vertexLighting * brdfData.diffuse;
  264. #endif
  265. return CalculateFinalColor(lightingData, surfaceData.alpha);
  266. }
  267. // Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
  268. half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
  269. half smoothness, half occlusion, half3 emission, half alpha)
  270. {
  271. SurfaceData surfaceData;
  272. surfaceData.albedo = albedo;
  273. surfaceData.specular = specular;
  274. surfaceData.metallic = metallic;
  275. surfaceData.smoothness = smoothness;
  276. surfaceData.normalTS = half3(0, 0, 1);
  277. surfaceData.emission = emission;
  278. surfaceData.occlusion = occlusion;
  279. surfaceData.alpha = alpha;
  280. surfaceData.clearCoatMask = 0;
  281. surfaceData.clearCoatSmoothness = 1;
  282. return UniversalFragmentPBR(inputData, surfaceData);
  283. }
  284. ////////////////////////////////////////////////////////////////////////////////
  285. /// Phong lighting...
  286. ////////////////////////////////////////////////////////////////////////////////
  287. half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData)
  288. {
  289. #if defined(DEBUG_DISPLAY)
  290. half4 debugColor;
  291. if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
  292. {
  293. return debugColor;
  294. }
  295. #endif
  296. uint meshRenderingLayers = GetMeshRenderingLightLayer();
  297. half4 shadowMask = CalculateShadowMask(inputData);
  298. AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
  299. Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);
  300. MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor);
  301. inputData.bakedGI *= surfaceData.albedo;
  302. LightingData lightingData = CreateLightingData(inputData, surfaceData);
  303. if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
  304. {
  305. lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData);
  306. }
  307. #if defined(_ADDITIONAL_LIGHTS)
  308. uint pixelLightCount = GetAdditionalLightsCount();
  309. #if USE_CLUSTERED_LIGHTING
  310. for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
  311. {
  312. Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
  313. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  314. {
  315. lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData);
  316. }
  317. }
  318. #endif
  319. LIGHT_LOOP_BEGIN(pixelLightCount)
  320. Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);
  321. if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
  322. {
  323. lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData);
  324. }
  325. LIGHT_LOOP_END
  326. #endif
  327. #if defined(_ADDITIONAL_LIGHTS_VERTEX)
  328. lightingData.vertexLightingColor += inputData.vertexLighting;
  329. #endif
  330. return CalculateFinalColor(lightingData, surfaceData.alpha);
  331. }
  332. // Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
  333. half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS)
  334. {
  335. SurfaceData surfaceData;
  336. surfaceData.albedo = diffuse;
  337. surfaceData.alpha = alpha;
  338. surfaceData.emission = emission;
  339. surfaceData.metallic = 0;
  340. surfaceData.occlusion = 1;
  341. surfaceData.smoothness = smoothness;
  342. surfaceData.specular = specularGloss.rgb;
  343. surfaceData.clearCoatMask = 0;
  344. surfaceData.clearCoatSmoothness = 1;
  345. surfaceData.normalTS = normalTS;
  346. return UniversalFragmentBlinnPhong(inputData, surfaceData);
  347. }
  348. ////////////////////////////////////////////////////////////////////////////////
  349. /// Unlit
  350. ////////////////////////////////////////////////////////////////////////////////
  351. half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)
  352. {
  353. #ifdef _ALPHAPREMULTIPLY_ON
  354. surfaceData.albedo *= surfaceData.alpha;
  355. #endif
  356. #if defined(DEBUG_DISPLAY)
  357. half4 debugColor;
  358. if (CanDebugOverrideOutputColor(inputData, surfaceData, debugColor))
  359. {
  360. return debugColor;
  361. }
  362. #endif
  363. AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
  364. LightingData lightingData = CreateLightingData(inputData, surfaceData);
  365. if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION))
  366. {
  367. lightingData.giColor *= aoFactor.indirectAmbientOcclusion;
  368. }
  369. return CalculateFinalColor(lightingData, surfaceData.albedo, surfaceData.alpha, inputData.fogCoord);
  370. }
  371. // Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments...
  372. half4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS)
  373. {
  374. SurfaceData surfaceData;
  375. surfaceData.albedo = color;
  376. surfaceData.alpha = alpha;
  377. surfaceData.emission = half3(0, 0, 0);
  378. surfaceData.metallic = 0;
  379. surfaceData.occlusion = 1;
  380. surfaceData.smoothness = 1;
  381. surfaceData.specular = half3(0, 0, 0);
  382. surfaceData.clearCoatMask = 0;
  383. surfaceData.clearCoatSmoothness = 1;
  384. surfaceData.normalTS = normalTS;
  385. return UniversalFragmentBakedLit(inputData, surfaceData);
  386. }
  387. #endif