pbrBlockSubSurface.fx 15 KB

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