pbrBlockSubSurface.fx 15 KB

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