Lux_Lighting_GGX_Anisotropic.hlsl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #if !defined(SHADERGRAPH_PREVIEW) || defined(LIGHTWEIGHT_LIGHTING_INCLUDED)
  2. // As we do not have access to the vertex lights we will make the shader always sample add lights per pixel
  3. #if defined(_ADDITIONAL_LIGHTS_VERTEX)
  4. #undef _ADDITIONAL_LIGHTS_VERTEX
  5. #define _ADDITIONAL_LIGHTS
  6. #endif
  7. #if defined(LIGHTWEIGHT_LIGHTING_INCLUDED) || defined(UNIVERSAL_LIGHTING_INCLUDED)
  8. struct AdditionalData {
  9. half3 tangentWS;
  10. half3 bitangentWS;
  11. float partLambdaV;
  12. half roughnessT;
  13. half roughnessB;
  14. half3 anisoReflectionNormal;
  15. };
  16. half3 DirectBDRF_LuxGGXAniso(BRDFData brdfData, AdditionalData addData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, half NdotL)
  17. {
  18. #ifndef _SPECULARHIGHLIGHTS_OFF
  19. float3 halfDir = SafeNormalize(lightDirectionWS + viewDirectionWS);
  20. float NoH = saturate(dot(normalWS, halfDir));
  21. half LoH = saturate(dot(lightDirectionWS, halfDir));
  22. half NdotV = saturate(dot(normalWS, viewDirectionWS ));
  23. // GGX Aniso
  24. float TdotH = dot(addData.tangentWS, halfDir);
  25. float TdotL = dot(addData.tangentWS, lightDirectionWS);
  26. float BdotH = dot(addData.bitangentWS, halfDir);
  27. float BdotL = dot(addData.bitangentWS, lightDirectionWS);
  28. float3 F = F_Schlick(brdfData.specular, LoH);
  29. //float TdotV = dot(addData.tangentWS, viewDirectionWS);
  30. //float BdotV = dot(addData.bitangentWS, viewDirectionWS);
  31. float DV = DV_SmithJointGGXAniso(
  32. TdotH, BdotH, NoH, NdotV, TdotL, BdotL, NdotL,
  33. addData.roughnessT, addData.roughnessB, addData.partLambdaV
  34. );
  35. // Check NdotL gets factores in outside as well.. correct?
  36. half3 specularLighting = F * DV;
  37. return specularLighting + brdfData.diffuse;
  38. #else
  39. return brdfData.diffuse;
  40. #endif
  41. }
  42. half3 LightingPhysicallyBased_LuxGGXAniso(BRDFData brdfData, AdditionalData addData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, half NdotL)
  43. {
  44. half3 radiance = lightColor * (lightAttenuation * NdotL);
  45. return DirectBDRF_LuxGGXAniso(brdfData, addData, normalWS, lightDirectionWS, viewDirectionWS, NdotL) * radiance;
  46. }
  47. half3 LightingPhysicallyBased_LuxGGXAniso(BRDFData brdfData, AdditionalData addData, Light light, half3 normalWS, half3 viewDirectionWS, half NdotL)
  48. {
  49. return LightingPhysicallyBased_LuxGGXAniso(brdfData, addData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, NdotL);
  50. }
  51. #endif
  52. #endif
  53. void Lighting_half(
  54. // Base inputs
  55. float3 positionWS,
  56. half3 viewDirectionWS,
  57. // Normal inputs
  58. half3 normalWS,
  59. half3 tangentWS,
  60. half3 bitangentWS,
  61. bool enableNormalMapping,
  62. half3 normalTS,
  63. // Surface description
  64. half3 albedo,
  65. half metallic,
  66. half3 specular,
  67. half smoothness,
  68. half occlusion,
  69. half alpha,
  70. // Lighting specific inputs
  71. half anisotropy,
  72. bool enableTransmission,
  73. half transmissionStrength,
  74. half transmissionPower,
  75. half transmissionDistortion,
  76. half transmissionShadowstrength,
  77. // Lightmapping
  78. float2 lightMapUV,
  79. // Final lit color
  80. out half3 MetaAlbedo,
  81. out half3 FinalLighting,
  82. out half3 MetaSpecular
  83. )
  84. {
  85. //#ifdef SHADERGRAPH_PREVIEW
  86. #if defined(SHADERGRAPH_PREVIEW) || ( !defined(LIGHTWEIGHT_LIGHTING_INCLUDED) && !defined(UNIVERSAL_LIGHTING_INCLUDED) )
  87. FinalLighting = albedo;
  88. MetaAlbedo = half3(0,0,0);
  89. MetaSpecular = half3(0,0,0);
  90. #else
  91. // Real Lighting ----------
  92. if (enableNormalMapping) {
  93. normalWS = TransformTangentToWorld(normalTS, half3x3(tangentWS.xyz, bitangentWS.xyz, normalWS.xyz));
  94. }
  95. normalWS = NormalizeNormalPerPixel(normalWS);
  96. viewDirectionWS = SafeNormalize(viewDirectionWS);
  97. // GI Lighting
  98. half3 bakedGI;
  99. #ifdef LIGHTMAP_ON
  100. lightMapUV = lightMapUV * unity_LightmapST.xy + unity_LightmapST.zw;
  101. bakedGI = SAMPLE_GI(lightMapUV, half3(0,0,0), normalWS);
  102. #else
  103. bakedGI = SampleSH(normalWS);
  104. #endif
  105. BRDFData brdfData;
  106. InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
  107. // Do not apply energy conservation
  108. brdfData.diffuse = albedo;
  109. brdfData.specular = specular;
  110. AdditionalData addData;
  111. // Adjust tangentWS in case normal mapping is active
  112. if (enableNormalMapping) {
  113. tangentWS = Orthonormalize(tangentWS, normalWS);
  114. }
  115. addData.tangentWS = tangentWS;
  116. addData.bitangentWS = cross(normalWS, tangentWS);
  117. // GGX Aniso
  118. addData.roughnessT = brdfData.roughness * (1 + anisotropy);
  119. addData.roughnessB = brdfData.roughness * (1 - anisotropy);
  120. float TdotV = dot(addData.tangentWS, viewDirectionWS);
  121. float BdotV = dot(addData.bitangentWS, viewDirectionWS);
  122. float NdotV = dot(normalWS, viewDirectionWS);
  123. addData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, addData.roughnessT, addData.roughnessB);
  124. // Set reflection normal and roughness – derived from GetGGXAnisotropicModifiedNormalAndRoughness
  125. half3 grainDirWS = (anisotropy >= 0.0) ? addData.bitangentWS : addData.tangentWS;
  126. half stretch = abs(anisotropy) * saturate(1.5h * sqrt(brdfData.perceptualRoughness));
  127. addData.anisoReflectionNormal = GetAnisotropicModifiedNormal(grainDirWS, normalWS, viewDirectionWS, stretch);
  128. half iblPerceptualRoughness = brdfData.perceptualRoughness * saturate(1.2h - abs(anisotropy));
  129. // Overwrite perceptual roughness for ambient specular reflections
  130. brdfData.perceptualRoughness = iblPerceptualRoughness;
  131. float4 clipPos = TransformWorldToHClip(positionWS);
  132. // Get Shadow Sampling Coords / Unfortunately per pixel...
  133. #if SHADOWS_SCREEN
  134. float4 shadowCoord = ComputeScreenPos(clipPos);
  135. #else
  136. float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
  137. #endif
  138. // Shadow mask
  139. #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
  140. half4 shadowMask = SAMPLE_SHADOWMASK(lightMapUV);
  141. #elif !defined (LIGHTMAP_ON)
  142. half4 shadowMask = unity_ProbesOcclusion;
  143. #else
  144. half4 shadowMask = half4(1, 1, 1, 1);
  145. #endif
  146. //Light mainLight = GetMainLight(shadowCoord);
  147. Light mainLight = GetMainLight(shadowCoord, positionWS, shadowMask);
  148. half3 mainLightColor = mainLight.color;
  149. // SSAO
  150. #if defined(_SCREEN_SPACE_OCCLUSION)
  151. float4 ndc = clipPos * 0.5f;
  152. float2 normalized = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
  153. normalized /= clipPos.w;
  154. normalized *= _ScreenParams.xy;
  155. // We could also use IN.Screenpos(default) --> ( IN.Screenpos.xy * _ScreenParams.xy)
  156. // HDRP 10.1
  157. normalized = GetNormalizedScreenSpaceUV(normalized);
  158. AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalized);
  159. mainLight.color *= aoFactor.directAmbientOcclusion;
  160. occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
  161. #endif
  162. MixRealtimeAndBakedGI(mainLight, normalWS, bakedGI, half4(0, 0, 0, 0));
  163. // GI
  164. FinalLighting = GlobalIllumination(brdfData, bakedGI, occlusion, addData.anisoReflectionNormal, viewDirectionWS);
  165. // Main Light
  166. half NdotL = saturate(dot(normalWS, mainLight.direction));
  167. FinalLighting += LightingPhysicallyBased_LuxGGXAniso(brdfData, addData, mainLight, normalWS, viewDirectionWS, NdotL);
  168. // transmission
  169. if(enableTransmission) {
  170. half3 transLightDir = mainLight.direction + normalWS * transmissionDistortion;
  171. half transDot = dot( transLightDir, -viewDirectionWS );
  172. transDot = exp2(saturate(transDot) * transmissionPower - transmissionPower);
  173. FinalLighting += brdfData.diffuse * transDot * (1.0h - NdotL) * mainLightColor * lerp(1.0h, mainLight.shadowAttenuation, transmissionShadowstrength) * transmissionStrength * 4;
  174. }
  175. // Handle additional lights
  176. #ifdef _ADDITIONAL_LIGHTS
  177. uint pixelLightCount = GetAdditionalLightsCount();
  178. for (uint i = 0u; i < pixelLightCount; ++i) {
  179. // Light light = GetAdditionalPerObjectLight(index, positionWS); // here; shadowAttenuation = 1.0;
  180. // URP 10: We have to use the new GetAdditionalLight function
  181. Light light = GetAdditionalLight(i, positionWS, shadowMask);
  182. half3 lightColor = light.color;
  183. #if defined(_SCREEN_SPACE_OCCLUSION)
  184. light.color *= aoFactor.directAmbientOcclusion;
  185. #endif
  186. NdotL = saturate(dot(normalWS, light.direction ));
  187. FinalLighting += LightingPhysicallyBased_LuxGGXAniso(brdfData, addData, light, normalWS, viewDirectionWS, NdotL);
  188. // transmission
  189. if(enableTransmission) {
  190. half3 transLightDir = light.direction + normalWS * transmissionDistortion;
  191. half transDot = dot( transLightDir, -viewDirectionWS );
  192. transDot = exp2(saturate(transDot) * transmissionPower - transmissionPower);
  193. NdotL = saturate(dot(normalWS, light.direction));
  194. FinalLighting += brdfData.diffuse * transDot * (1.0h - NdotL) * lightColor * lerp(1.0h, light.shadowAttenuation, transmissionShadowstrength) * light.distanceAttenuation * transmissionStrength * 4;
  195. }
  196. }
  197. #endif
  198. // Set Albedo for meta pass
  199. #if defined(LIGHTWEIGHT_META_PASS_INCLUDED) || defined(UNIVERSAL_META_PASS_INCLUDED)
  200. FinalLighting = half3(0,0,0);
  201. MetaAlbedo = albedo;
  202. MetaSpecular = specular;
  203. #else
  204. MetaAlbedo = half3(0,0,0);
  205. MetaSpecular = half3(0,0,0);
  206. #endif
  207. // End Real Lighting ----------
  208. #endif
  209. }
  210. // Unity 2019.1. needs a float version
  211. void Lighting_float(
  212. // Base inputs
  213. float3 positionWS,
  214. half3 viewDirectionWS,
  215. // Normal inputs
  216. half3 normalWS,
  217. half3 tangentWS,
  218. half3 bitangentWS,
  219. bool enableNormalMapping,
  220. half3 normalTS,
  221. // Surface description
  222. half3 albedo,
  223. half metallic,
  224. half3 specular,
  225. half smoothness,
  226. half occlusion,
  227. half alpha,
  228. // Lighting specific inputs
  229. half anisotropy,
  230. bool enableTransmission,
  231. half transmissionStrength,
  232. half transmissionPower,
  233. half transmissionDistortion,
  234. half transmissionShadowstrength,
  235. // Lightmapping
  236. float2 lightMapUV,
  237. // Final lit color
  238. out half3 MetaAlbedo,
  239. out half3 FinalLighting,
  240. out half3 MetaSpecular
  241. )
  242. {
  243. Lighting_half(
  244. positionWS, viewDirectionWS, normalWS, tangentWS, bitangentWS, enableNormalMapping, normalTS,
  245. albedo, metallic, specular, smoothness, occlusion, alpha,
  246. anisotropy, enableTransmission, transmissionStrength, transmissionPower, transmissionDistortion, transmissionShadowstrength,
  247. lightMapUV, MetaAlbedo, FinalLighting, MetaSpecular);
  248. }