pbrBlockSubSurface.fx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. struct subSurfaceOutParams
  2. {
  3. vec3 specularEnvironmentReflectance;
  4. #ifdef SS_REFRACTION
  5. vec3 finalRefraction;
  6. vec3 surfaceAlbedo;
  7. #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
  8. float alpha;
  9. #endif
  10. #ifdef REFLECTION
  11. float refractionFactorForIrradiance;
  12. #endif
  13. #endif
  14. #ifdef SS_TRANSLUCENCY
  15. vec3 transmittance;
  16. #ifdef REFLECTION
  17. vec3 refractionIrradiance;
  18. #endif
  19. #endif
  20. #if DEBUGMODE > 0
  21. vec4 thicknessMap;
  22. vec4 environmentRefraction;
  23. vec3 refractionTransmittance;
  24. #endif
  25. };
  26. #ifdef SUBSURFACE
  27. #define inline
  28. void subSurfaceBlock(
  29. const in vec3 vSubSurfaceIntensity,
  30. const in vec2 vThicknessParam,
  31. const in vec4 vTintColor,
  32. const in vec3 normalW,
  33. const in vec3 specularEnvironmentReflectance,
  34. #ifdef SS_THICKNESSANDMASK_TEXTURE
  35. const in vec4 thicknessMap,
  36. #endif
  37. #ifdef REFLECTION
  38. #ifdef SS_TRANSLUCENCY
  39. const in mat4 reflectionMatrix,
  40. #ifdef USESPHERICALFROMREFLECTIONMAP
  41. #if !defined(NORMAL) || !defined(USESPHERICALINVERTEX)
  42. const in vec3 irradianceVector_,
  43. #endif
  44. #endif
  45. #ifdef USEIRRADIANCEMAP
  46. #ifdef REFLECTIONMAP_3D
  47. const in samplerCube irradianceSampler,
  48. #else
  49. const in sampler2D irradianceSampler,
  50. #endif
  51. #endif
  52. #endif
  53. #endif
  54. #ifdef SS_REFRACTION
  55. const in vec3 vPositionW,
  56. const in vec3 viewDirectionW,
  57. const in mat4 view,
  58. const in vec3 surfaceAlbedo,
  59. const in vec4 vRefractionInfos,
  60. const in mat4 refractionMatrix,
  61. const in vec3 vRefractionMicrosurfaceInfos,
  62. const in vec4 vLightingIntensity,
  63. #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
  64. const in float alpha,
  65. #endif
  66. #ifdef SS_LODINREFRACTIONALPHA
  67. const in float NdotVUnclamped,
  68. #endif
  69. #ifdef SS_LINEARSPECULARREFRACTION
  70. const in float roughness,
  71. #else
  72. const in float alphaG,
  73. #endif
  74. #ifdef SS_REFRACTIONMAP_3D
  75. const in samplerCube refractionSampler,
  76. #ifndef LODBASEDMICROSFURACE
  77. const in samplerCube refractionSamplerLow,
  78. const in samplerCube refractionSamplerHigh,
  79. #endif
  80. #else
  81. const in sampler2D refractionSampler,
  82. #ifndef LODBASEDMICROSFURACE
  83. const in sampler2D refractionSamplerLow,
  84. const in sampler2D refractionSamplerHigh,
  85. #endif
  86. #endif
  87. #ifdef ANISOTROPIC
  88. const in anisotropicOutParams anisotropicOut,
  89. #endif
  90. #endif
  91. #ifdef SS_TRANSLUCENCY
  92. const in vec3 vDiffusionDistance,
  93. #endif
  94. out subSurfaceOutParams outParams
  95. )
  96. {
  97. outParams.specularEnvironmentReflectance = specularEnvironmentReflectance;
  98. // ______________________________________________________________________________________
  99. // _____________________________ Intensities & thickness ________________________________
  100. // ______________________________________________________________________________________
  101. #ifdef SS_REFRACTION
  102. float refractionIntensity = vSubSurfaceIntensity.x;
  103. #ifdef SS_LINKREFRACTIONTOTRANSPARENCY
  104. refractionIntensity *= (1.0 - alpha);
  105. // Put alpha back to 1;
  106. outParams.alpha = 1.0;
  107. #endif
  108. #endif
  109. #ifdef SS_TRANSLUCENCY
  110. float translucencyIntensity = vSubSurfaceIntensity.y;
  111. #endif
  112. #ifdef SS_SCATTERING
  113. float scatteringIntensity = vSubSurfaceIntensity.z;
  114. #endif
  115. #ifdef SS_THICKNESSANDMASK_TEXTURE
  116. float thickness = thicknessMap.r * vThicknessParam.y + vThicknessParam.x;
  117. #if DEBUGMODE > 0
  118. outParams.thicknessMap = thicknessMap;
  119. #endif
  120. #ifdef SS_MASK_FROM_THICKNESS_TEXTURE
  121. #ifdef SS_REFRACTION
  122. refractionIntensity *= thicknessMap.g;
  123. #endif
  124. #ifdef SS_TRANSLUCENCY
  125. translucencyIntensity *= thicknessMap.b;
  126. #endif
  127. #ifdef SS_SCATTERING
  128. scatteringIntensity *= thicknessMap.a;
  129. #endif
  130. #endif
  131. #else
  132. float thickness = vThicknessParam.y;
  133. #endif
  134. // _________________________________________________________________________________________
  135. // _____________________________ Translucency transmittance ________________________________
  136. // _________________________________________________________________________________________
  137. #ifdef SS_TRANSLUCENCY
  138. thickness = maxEps(thickness);
  139. vec3 transmittance = transmittanceBRDF_Burley(vTintColor.rgb, vDiffusionDistance, thickness);
  140. transmittance *= translucencyIntensity;
  141. outParams.transmittance = transmittance;
  142. #endif
  143. // _____________________________________________________________________________________
  144. // _____________________________ Refraction environment ________________________________
  145. // _____________________________________________________________________________________
  146. #ifdef SS_REFRACTION
  147. vec4 environmentRefraction = vec4(0., 0., 0., 0.);
  148. #ifdef ANISOTROPIC
  149. vec3 refractionVector = refract(-viewDirectionW, anisotropicOut.anisotropicNormal, vRefractionInfos.y);
  150. #else
  151. vec3 refractionVector = refract(-viewDirectionW, normalW, vRefractionInfos.y);
  152. #endif
  153. #ifdef SS_REFRACTIONMAP_OPPOSITEZ
  154. refractionVector.z *= -1.0;
  155. #endif
  156. // _____________________________ 2D vs 3D Maps ________________________________
  157. #ifdef SS_REFRACTIONMAP_3D
  158. refractionVector.y = refractionVector.y * vRefractionInfos.w;
  159. vec3 refractionCoords = refractionVector;
  160. refractionCoords = vec3(refractionMatrix * vec4(refractionCoords, 0));
  161. #else
  162. vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
  163. vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
  164. refractionCoords.y = 1.0 - refractionCoords.y;
  165. #endif
  166. #ifdef SS_LODINREFRACTIONALPHA
  167. float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG, NdotVUnclamped);
  168. #elif defined(SS_LINEARSPECULARREFRACTION)
  169. float refractionLOD = getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x, roughness);
  170. #else
  171. float refractionLOD = getLodFromAlphaG(vRefractionMicrosurfaceInfos.x, alphaG);
  172. #endif
  173. #ifdef LODBASEDMICROSFURACE
  174. // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
  175. refractionLOD = refractionLOD * vRefractionMicrosurfaceInfos.y + vRefractionMicrosurfaceInfos.z;
  176. #ifdef SS_LODINREFRACTIONALPHA
  177. // Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
  178. // is constrained to appropriate LOD levels in order to prevent aliasing.
  179. // The environment map is first sampled without custom LOD selection to determine
  180. // the hardware-selected LOD, and this is then used to constrain the final LOD selection
  181. // so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
  182. // where the normal is varying rapidly).
  183. // Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
  184. // manual calculation via derivatives is also possible, but for simplicity we use the
  185. // hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
  186. float automaticRefractionLOD = UNPACK_LOD(sampleRefraction(refractionSampler, refractionCoords).a);
  187. float requestedRefractionLOD = max(automaticRefractionLOD, refractionLOD);
  188. #else
  189. float requestedRefractionLOD = refractionLOD;
  190. #endif
  191. #ifdef REALTIME_FILTERING
  192. #ifdef SS_LINEARSPECULARREFRACTION
  193. environmentRefraction = vec4(radiance(roughness, refractionSampler, refractionCoords, vRefractionFilteringInfo), 1.0);
  194. #else
  195. environmentRefraction = vec4(radiance(alphaG, refractionSampler, refractionCoords, vRefractionFilteringInfo), 1.0);
  196. #endif
  197. #else
  198. environmentRefraction = sampleRefractionLod(refractionSampler, refractionCoords, requestedRefractionLOD);
  199. #endif
  200. #else
  201. float lodRefractionNormalized = saturate(refractionLOD / log2(vRefractionMicrosurfaceInfos.x));
  202. float lodRefractionNormalizedDoubled = lodRefractionNormalized * 2.0;
  203. vec4 environmentRefractionMid = sampleRefraction(refractionSampler, refractionCoords);
  204. if (lodRefractionNormalizedDoubled < 1.0){
  205. environmentRefraction = mix(
  206. sampleRefraction(refractionSamplerHigh, refractionCoords),
  207. environmentRefractionMid,
  208. lodRefractionNormalizedDoubled
  209. );
  210. } else {
  211. environmentRefraction = mix(
  212. environmentRefractionMid,
  213. sampleRefraction(refractionSamplerLow, refractionCoords),
  214. lodRefractionNormalizedDoubled - 1.0
  215. );
  216. }
  217. #endif
  218. #ifdef SS_RGBDREFRACTION
  219. environmentRefraction.rgb = fromRGBD(environmentRefraction);
  220. #endif
  221. #ifdef SS_GAMMAREFRACTION
  222. environmentRefraction.rgb = toLinearSpace(environmentRefraction.rgb);
  223. #endif
  224. // _____________________________ Levels _____________________________________
  225. environmentRefraction.rgb *= vRefractionInfos.x;
  226. #endif
  227. // _______________________________________________________________________________
  228. // _____________________________ Final Refraction ________________________________
  229. // _______________________________________________________________________________
  230. #ifdef SS_REFRACTION
  231. vec3 refractionTransmittance = vec3(refractionIntensity);
  232. #ifdef SS_THICKNESSANDMASK_TEXTURE
  233. vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
  234. // // Simulate Flat Surface
  235. // thickness /= dot(refractionVector, -normalW);
  236. // // Simulate Curved Surface
  237. // float NdotRefract = dot(normalW, refractionVector);
  238. // thickness *= -NdotRefract;
  239. refractionTransmittance *= cocaLambert(volumeAlbedo, thickness);
  240. #elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)
  241. // Tint the material with albedo.
  242. float maxChannel = max(max(surfaceAlbedo.r, surfaceAlbedo.g), surfaceAlbedo.b);
  243. vec3 volumeAlbedo = saturate(maxChannel * surfaceAlbedo);
  244. // Tint reflectance
  245. environmentRefraction.rgb *= volumeAlbedo;
  246. #else
  247. // Compute tint from min distance only.
  248. vec3 volumeAlbedo = computeColorAtDistanceInMedia(vTintColor.rgb, vTintColor.w);
  249. refractionTransmittance *= cocaLambert(volumeAlbedo, vThicknessParam.y);
  250. #endif
  251. // Decrease Albedo Contribution
  252. outParams.surfaceAlbedo = surfaceAlbedo * (1. - refractionIntensity);
  253. #ifdef REFLECTION
  254. // Decrease irradiance Contribution
  255. outParams.refractionFactorForIrradiance = (1. - refractionIntensity);
  256. //environmentIrradiance *= (1. - refractionIntensity);
  257. #endif
  258. // Add Multiple internal bounces.
  259. vec3 bounceSpecularEnvironmentReflectance = (2.0 * specularEnvironmentReflectance) / (1.0 + specularEnvironmentReflectance);
  260. outParams.specularEnvironmentReflectance = mix(bounceSpecularEnvironmentReflectance, specularEnvironmentReflectance, refractionIntensity);
  261. // In theory T = 1 - R.
  262. refractionTransmittance *= 1.0 - outParams.specularEnvironmentReflectance;
  263. #if DEBUGMODE > 0
  264. outParams.refractionTransmittance = refractionTransmittance;
  265. #endif
  266. outParams.finalRefraction = environmentRefraction.rgb * refractionTransmittance * vLightingIntensity.z;
  267. #if DEBUGMODE > 0
  268. outParams.environmentRefraction = environmentRefraction;
  269. #endif
  270. #endif
  271. // __________________________________________________________________________________
  272. // _______________________________ IBL Translucency ________________________________
  273. // __________________________________________________________________________________
  274. #if defined(REFLECTION) && defined(SS_TRANSLUCENCY)
  275. #if defined(NORMAL) && defined(USESPHERICALINVERTEX) || !defined(USESPHERICALFROMREFLECTIONMAP)
  276. vec3 irradianceVector = vec3(reflectionMatrix * vec4(normalW, 0)).xyz;
  277. #ifdef REFLECTIONMAP_OPPOSITEZ
  278. irradianceVector.z *= -1.0;
  279. #endif
  280. #ifdef INVERTCUBICMAP
  281. irradianceVector.y *= -1.0;
  282. #endif
  283. #else
  284. vec3 irradianceVector = irradianceVector_;
  285. #endif
  286. #if defined(USESPHERICALFROMREFLECTIONMAP)
  287. #if defined(REALTIME_FILTERING)
  288. vec3 refractionIrradiance = irradiance(reflectionSampler, -irradianceVector, vReflectionFilteringInfo);
  289. #else
  290. vec3 refractionIrradiance = computeEnvironmentIrradiance(-irradianceVector);
  291. #endif
  292. #elif defined(USEIRRADIANCEMAP)
  293. #ifdef REFLECTIONMAP_3D
  294. vec3 irradianceCoords = irradianceVector;
  295. #else
  296. vec2 irradianceCoords = irradianceVector.xy;
  297. #ifdef REFLECTIONMAP_PROJECTION
  298. irradianceCoords /= irradianceVector.z;
  299. #endif
  300. irradianceCoords.y = 1.0 - irradianceCoords.y;
  301. #endif
  302. vec4 refractionIrradiance = sampleReflection(irradianceSampler, -irradianceCoords);
  303. #ifdef RGBDREFLECTION
  304. refractionIrradiance.rgb = fromRGBD(refractionIrradiance);
  305. #endif
  306. #ifdef GAMMAREFLECTION
  307. refractionIrradiance.rgb = toLinearSpace(refractionIrradiance.rgb);
  308. #endif
  309. #else
  310. vec4 refractionIrradiance = vec4(0.);
  311. #endif
  312. refractionIrradiance.rgb *= transmittance;
  313. outParams.refractionIrradiance = refractionIrradiance.rgb;
  314. #endif
  315. }
  316. #endif