Lux_Lighting_CharlieSheen.hlsl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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. // Ref: https://knarkowicz.wordpress.com/2018/01/04/cloth-shading/
  9. real D_CharlieNoPI_Lux(real NdotH, real roughness)
  10. {
  11. float invR = rcp(roughness);
  12. float cos2h = NdotH * NdotH;
  13. float sin2h = 1.0 - cos2h;
  14. // Note: We have sin^2 so multiply by 0.5 to cancel it
  15. return (2.0 + invR) * PositivePow(sin2h, invR * 0.5) / 2.0;
  16. }
  17. real D_Charlie_Lux(real NdotH, real roughness)
  18. {
  19. return INV_PI * D_CharlieNoPI_Lux(NdotH, roughness);
  20. }
  21. // We use V_Ashikhmin instead of V_Charlie in practice for game due to the cost of V_Charlie
  22. real V_Ashikhmin_Lux(real NdotL, real NdotV)
  23. {
  24. // Use soft visibility term introduce in: Crafting a Next-Gen Material Pipeline for The Order : 1886
  25. return 1.0 / (4.0 * (NdotL + NdotV - NdotL * NdotV));
  26. }
  27. // A diffuse term use with fabric done by tech artist - empirical
  28. real FabricLambertNoPI_Lux(real roughness)
  29. {
  30. return lerp(1.0, 0.5, roughness);
  31. }
  32. real FabricLambert_Lux(real roughness)
  33. {
  34. return INV_PI * FabricLambertNoPI_Lux(roughness);
  35. }
  36. struct AdditionalData {
  37. half3 sheenColor;
  38. };
  39. half3 DirectBDRF_LuxCharlieSheen(BRDFData brdfData, AdditionalData addData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, half NdotL)
  40. {
  41. #ifndef _SPECULARHIGHLIGHTS_OFF
  42. float3 halfDir = SafeNormalize(lightDirectionWS + viewDirectionWS);
  43. float NoH = saturate(dot(normalWS, halfDir));
  44. half LoH = saturate(dot(lightDirectionWS, halfDir));
  45. half NdotV = saturate(dot(normalWS, viewDirectionWS ));
  46. // Charlie Sheen
  47. // NOTE: We use the noPI version here!!!!!!
  48. float D = D_CharlieNoPI_Lux(NoH, brdfData.roughness);
  49. // Unity: V_Charlie is expensive, use approx with V_Ashikhmin instead
  50. // Unity: float Vis = V_Charlie(NdotL, NdotV, bsdfData.roughness);
  51. float Vis = V_Ashikhmin_Lux(NdotL, NdotV);
  52. // Unity: Fabrics are dieletric but we simulate forward scattering effect with colored specular (fuzz tint term)
  53. // Unity: We don't use Fresnel term for CharlieD
  54. // SheenColor seemed way too dark (compared to HDRP) – so i multiply it with PI which looked ok and somehow matched HDRP
  55. // Therefore we use the noPI charlie version. As PI is a constant factor the artists can tweak the look by adjusting the sheen color.
  56. float3 F = addData.sheenColor; // * PI;
  57. half3 specularLighting = F * Vis * D;
  58. // Unity: Note: diffuseLighting originally is multiply by color in PostEvaluateBSDF
  59. // So we do it here :)
  60. // Using saturate to get rid of artifacts around the borders.
  61. return saturate(specularLighting) + brdfData.diffuse * FabricLambert_Lux(brdfData.roughness);
  62. #else
  63. return brdfData.diffuse;
  64. #endif
  65. }
  66. half3 LightingPhysicallyBased_LuxCharlieSheen(BRDFData brdfData, AdditionalData addData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, half NdotL)
  67. {
  68. //half NdotL = saturate(dot(normalWS, lightDirectionWS));
  69. half3 radiance = lightColor * (lightAttenuation * NdotL);
  70. return DirectBDRF_LuxCharlieSheen(brdfData, addData, normalWS, lightDirectionWS, viewDirectionWS, NdotL) * radiance;
  71. }
  72. half3 LightingPhysicallyBased_LuxCharlieSheen(BRDFData brdfData, AdditionalData addData, Light light, half3 normalWS, half3 viewDirectionWS, half NdotL)
  73. {
  74. return LightingPhysicallyBased_LuxCharlieSheen(brdfData, addData, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, NdotL);
  75. }
  76. #endif
  77. #endif
  78. void Lighting_half(
  79. // Base inputs
  80. float3 positionWS,
  81. half3 viewDirectionWS,
  82. // Normal inputs
  83. half3 normalWS,
  84. half3 tangentWS,
  85. half3 bitangentWS,
  86. bool enableNormalMapping,
  87. half3 normalTS,
  88. // Surface description
  89. half3 albedo,
  90. half metallic,
  91. half3 specular,
  92. half smoothness,
  93. half occlusion,
  94. half alpha,
  95. // Lighting specific inputs
  96. half3 sheenColor,
  97. bool enableTransmission,
  98. half transmissionStrength,
  99. half transmissionPower,
  100. half transmissionDistortion,
  101. half transmissionShadowstrength,
  102. // Lightmapping
  103. float2 lightMapUV,
  104. // Final lit color
  105. out half3 MetaAlbedo,
  106. out half3 FinalLighting,
  107. out half3 MetaSpecular
  108. )
  109. {
  110. #if defined(SHADERGRAPH_PREVIEW) || ( !defined(LIGHTWEIGHT_LIGHTING_INCLUDED) && !defined(UNIVERSAL_LIGHTING_INCLUDED) )
  111. FinalLighting = albedo;
  112. MetaAlbedo = half3(0,0,0);
  113. MetaSpecular = half3(0,0,0);
  114. #else
  115. // Real Lighting ----------
  116. // Charlie Sheen specific:
  117. smoothness = lerp(0.0h, 0.6h, smoothness);
  118. if (enableNormalMapping) {
  119. normalWS = TransformTangentToWorld(normalTS, half3x3(tangentWS.xyz, bitangentWS.xyz, normalWS.xyz));
  120. }
  121. normalWS = NormalizeNormalPerPixel(normalWS);
  122. viewDirectionWS = SafeNormalize(viewDirectionWS);
  123. // GI Lighting
  124. half3 bakedGI;
  125. #ifdef LIGHTMAP_ON
  126. lightMapUV = lightMapUV * unity_LightmapST.xy + unity_LightmapST.zw;
  127. bakedGI = SAMPLE_GI(lightMapUV, half3(0,0,0), normalWS);
  128. #else
  129. bakedGI = SampleSH(normalWS);
  130. #endif
  131. BRDFData brdfData;
  132. InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
  133. // Do not apply energy conservation
  134. brdfData.diffuse = albedo;
  135. brdfData.specular = specular;
  136. AdditionalData addData;
  137. //addData.tangentWS = tangentWS;
  138. //addData.bitangentWS = bitangentWS;
  139. // Charlie Sheen
  140. //addData.partLambdaV = 0.0h;
  141. //addData.anisoReflectionNormal = normalWS;
  142. float NdotV = dot(normalWS, viewDirectionWS);
  143. addData.sheenColor = sheenColor;
  144. float4 clipPos = TransformWorldToHClip(positionWS);
  145. // Get Shadow Sampling Coords / Unfortunately per pixel...
  146. #if SHADOWS_SCREEN
  147. float4 shadowCoord = ComputeScreenPos(clipPos);
  148. #else
  149. float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
  150. #endif
  151. // Shadow mask
  152. #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
  153. half4 shadowMask = SAMPLE_SHADOWMASK(lightMapUV);
  154. #elif !defined (LIGHTMAP_ON)
  155. half4 shadowMask = unity_ProbesOcclusion;
  156. #else
  157. half4 shadowMask = half4(1, 1, 1, 1);
  158. #endif
  159. //Light mainLight = GetMainLight(shadowCoord);
  160. Light mainLight = GetMainLight(shadowCoord, positionWS, shadowMask);
  161. half3 mainLightColor = mainLight.color;
  162. // SSAO
  163. #if defined(_SCREEN_SPACE_OCCLUSION)
  164. float4 ndc = clipPos * 0.5f;
  165. float2 normalized = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
  166. normalized /= clipPos.w;
  167. normalized *= _ScreenParams.xy;
  168. // We could also use IN.Screenpos(default) --> ( IN.Screenpos.xy * _ScreenParams.xy)
  169. // HDRP 10.1
  170. normalized = GetNormalizedScreenSpaceUV(normalized);
  171. AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalized);
  172. mainLight.color *= aoFactor.directAmbientOcclusion;
  173. occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
  174. #endif
  175. MixRealtimeAndBakedGI(mainLight, normalWS, bakedGI, half4(0, 0, 0, 0));
  176. // GI
  177. FinalLighting = GlobalIllumination(brdfData, bakedGI, occlusion, normalWS, viewDirectionWS);
  178. // Main Light
  179. half NdotL = saturate(dot(normalWS, mainLight.direction));
  180. FinalLighting += LightingPhysicallyBased_LuxCharlieSheen(brdfData, addData, mainLight, normalWS, viewDirectionWS, NdotL);
  181. // transmission
  182. if (enableTransmission) {
  183. half3 transLightDir = mainLight.direction + normalWS * transmissionDistortion;
  184. half transDot = dot( transLightDir, -viewDirectionWS );
  185. transDot = exp2(saturate(transDot) * transmissionPower - transmissionPower);
  186. FinalLighting += brdfData.diffuse * transDot * (1.0h - NdotL) * mainLightColor * lerp(1.0h, mainLight.shadowAttenuation, transmissionShadowstrength) * transmissionStrength * 4;
  187. }
  188. // Handle additional lights
  189. #ifdef _ADDITIONAL_LIGHTS
  190. uint pixelLightCount = GetAdditionalLightsCount();
  191. for (uint i = 0u; i < pixelLightCount; ++i) {
  192. // Light light = GetAdditionalPerObjectLight(index, positionWS); // here; shadowAttenuation = 1.0;
  193. // URP 10: We have to use the new GetAdditionalLight function
  194. Light light = GetAdditionalLight(i, positionWS, shadowMask);
  195. half3 lightColor = light.color;
  196. #if defined(_SCREEN_SPACE_OCCLUSION)
  197. light.color *= aoFactor.directAmbientOcclusion;
  198. #endif
  199. NdotL = saturate(dot(normalWS, light.direction ));
  200. FinalLighting += LightingPhysicallyBased_LuxCharlieSheen(brdfData, addData, light, normalWS, viewDirectionWS, NdotL);
  201. // transmission
  202. if (enableTransmission) {
  203. half3 transLightDir = light.direction + normalWS * transmissionDistortion;
  204. half transDot = dot( transLightDir, -viewDirectionWS );
  205. transDot = exp2(saturate(transDot) * transmissionPower - transmissionPower);
  206. NdotL = saturate(dot(normalWS, light.direction));
  207. FinalLighting += brdfData.diffuse * transDot * (1.0h - NdotL) * lightColor * lerp(1.0h, light.shadowAttenuation, transmissionShadowstrength) * light.distanceAttenuation * transmissionStrength * 4;
  208. }
  209. }
  210. #endif
  211. // Set Albedo for meta pass
  212. #if defined(LIGHTWEIGHT_META_PASS_INCLUDED) || defined(UNIVERSAL_META_PASS_INCLUDED)
  213. FinalLighting = half3(0,0,0);
  214. MetaAlbedo = albedo;
  215. MetaSpecular = specular;
  216. #else
  217. MetaAlbedo = half3(0,0,0);
  218. MetaSpecular = half3(0,0,0);
  219. #endif
  220. // End Real Lighting ----------
  221. #endif
  222. }
  223. // Unity 2019.1. needs a float version
  224. void Lighting_float(
  225. // Base inputs
  226. float3 positionWS,
  227. half3 viewDirectionWS,
  228. // Normal inputs
  229. half3 normalWS,
  230. half3 tangentWS,
  231. half3 bitangentWS,
  232. bool enableNormalMapping,
  233. half3 normalTS,
  234. // Surface description
  235. half3 albedo,
  236. half metallic,
  237. half3 specular,
  238. half smoothness,
  239. half occlusion,
  240. half alpha,
  241. // Lighting specific inputs
  242. half3 sheenColor,
  243. bool enableTransmission,
  244. half transmissionStrength,
  245. half transmissionPower,
  246. half transmissionDistortion,
  247. half transmissionShadowstrength,
  248. // Lightmapping
  249. float2 lightMapUV,
  250. // Final lit color
  251. out half3 MetaAlbedo,
  252. out half3 FinalLighting,
  253. out half3 MetaSpecular
  254. )
  255. {
  256. Lighting_half(
  257. positionWS, viewDirectionWS, normalWS, tangentWS, bitangentWS, enableNormalMapping, normalTS,
  258. albedo, metallic, specular, smoothness, occlusion, alpha,
  259. sheenColor, enableTransmission, transmissionStrength, transmissionPower, transmissionDistortion, transmissionShadowstrength,
  260. lightMapUV, MetaAlbedo, FinalLighting, MetaSpecular);
  261. }