pbrSubSurfaceConfiguration.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. import { __decorate } from "../../tslib.es6.js";
  2. import { serialize, serializeAsTexture, expandToProperty, serializeAsColor3 } from "../../Misc/decorators.js";
  3. import { Color3 } from "../../Maths/math.color.js";
  4. import { MaterialFlags } from "../materialFlags.js";
  5. import { Scalar } from "../../Maths/math.scalar.js";
  6. import { TmpVectors } from "../../Maths/math.vector.js";
  7. import { MaterialPluginBase } from "../materialPluginBase.js";
  8. import { MaterialDefines } from "../materialDefines.js";
  9. import { BindTextureMatrix, PrepareDefinesForMergedUV } from "../materialHelper.functions.js";
  10. /**
  11. * @internal
  12. */
  13. export class MaterialSubSurfaceDefines extends MaterialDefines {
  14. constructor() {
  15. super(...arguments);
  16. this.SUBSURFACE = false;
  17. this.SS_REFRACTION = false;
  18. this.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;
  19. this.SS_TRANSLUCENCY = false;
  20. this.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;
  21. this.SS_SCATTERING = false;
  22. this.SS_DISPERSION = false;
  23. this.SS_THICKNESSANDMASK_TEXTURE = false;
  24. this.SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;
  25. this.SS_HAS_THICKNESS = false;
  26. this.SS_REFRACTIONINTENSITY_TEXTURE = false;
  27. this.SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV = 0;
  28. this.SS_TRANSLUCENCYINTENSITY_TEXTURE = false;
  29. this.SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV = 0;
  30. this.SS_REFRACTIONMAP_3D = false;
  31. this.SS_REFRACTIONMAP_OPPOSITEZ = false;
  32. this.SS_LODINREFRACTIONALPHA = false;
  33. this.SS_GAMMAREFRACTION = false;
  34. this.SS_RGBDREFRACTION = false;
  35. this.SS_LINEARSPECULARREFRACTION = false;
  36. this.SS_LINKREFRACTIONTOTRANSPARENCY = false;
  37. this.SS_ALBEDOFORREFRACTIONTINT = false;
  38. this.SS_ALBEDOFORTRANSLUCENCYTINT = false;
  39. this.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;
  40. this.SS_USE_THICKNESS_AS_DEPTH = false;
  41. this.SS_USE_GLTF_TEXTURES = false;
  42. }
  43. }
  44. /**
  45. * Plugin that implements the sub surface component of the PBR material
  46. */
  47. export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
  48. /**
  49. * Diffusion profile for subsurface scattering.
  50. * Useful for better scattering in the skins or foliages.
  51. */
  52. get scatteringDiffusionProfile() {
  53. if (!this._scene.subSurfaceConfiguration) {
  54. return null;
  55. }
  56. return this._scene.subSurfaceConfiguration.ssDiffusionProfileColors[this._scatteringDiffusionProfileIndex];
  57. }
  58. set scatteringDiffusionProfile(c) {
  59. if (!this._scene.enableSubSurfaceForPrePass()) {
  60. // Not supported
  61. return;
  62. }
  63. // addDiffusionProfile automatically checks for doubles
  64. if (c) {
  65. this._scatteringDiffusionProfileIndex = this._scene.subSurfaceConfiguration.addDiffusionProfile(c);
  66. }
  67. }
  68. /**
  69. * Index of refraction of the material's volume.
  70. * https://en.wikipedia.org/wiki/List_of_refractive_indices
  71. *
  72. * This ONLY impacts refraction. If not provided or given a non-valid value,
  73. * the volume will use the same IOR as the surface.
  74. */
  75. get volumeIndexOfRefraction() {
  76. if (this._volumeIndexOfRefraction >= 1.0) {
  77. return this._volumeIndexOfRefraction;
  78. }
  79. return this._indexOfRefraction;
  80. }
  81. set volumeIndexOfRefraction(value) {
  82. if (value >= 1.0) {
  83. this._volumeIndexOfRefraction = value;
  84. }
  85. else {
  86. this._volumeIndexOfRefraction = -1.0;
  87. }
  88. }
  89. /** @internal */
  90. _markAllSubMeshesAsTexturesDirty() {
  91. this._enable(this._isRefractionEnabled || this._isTranslucencyEnabled || this._isScatteringEnabled);
  92. this._internalMarkAllSubMeshesAsTexturesDirty();
  93. }
  94. /** @internal */
  95. _markScenePrePassDirty() {
  96. this._internalMarkAllSubMeshesAsTexturesDirty();
  97. this._internalMarkScenePrePassDirty();
  98. }
  99. constructor(material, addToPluginList = true) {
  100. super(material, "PBRSubSurface", 130, new MaterialSubSurfaceDefines(), addToPluginList);
  101. this._isRefractionEnabled = false;
  102. /**
  103. * Defines if the refraction is enabled in the material.
  104. */
  105. this.isRefractionEnabled = false;
  106. this._isTranslucencyEnabled = false;
  107. /**
  108. * Defines if the translucency is enabled in the material.
  109. */
  110. this.isTranslucencyEnabled = false;
  111. this._isDispersionEnabled = false;
  112. /**
  113. * Defines if dispersion is enabled in the material.
  114. */
  115. this.isDispersionEnabled = false;
  116. this._isScatteringEnabled = false;
  117. /**
  118. * Defines if the sub surface scattering is enabled in the material.
  119. */
  120. this.isScatteringEnabled = false;
  121. this._scatteringDiffusionProfileIndex = 0;
  122. /**
  123. * Defines the refraction intensity of the material.
  124. * The refraction when enabled replaces the Diffuse part of the material.
  125. * The intensity helps transitioning between diffuse and refraction.
  126. */
  127. this.refractionIntensity = 1;
  128. /**
  129. * Defines the translucency intensity of the material.
  130. * When translucency has been enabled, this defines how much of the "translucency"
  131. * is added to the diffuse part of the material.
  132. */
  133. this.translucencyIntensity = 1;
  134. /**
  135. * When enabled, transparent surfaces will be tinted with the albedo colour (independent of thickness)
  136. */
  137. this.useAlbedoToTintRefraction = false;
  138. /**
  139. * When enabled, translucent surfaces will be tinted with the albedo colour (independent of thickness)
  140. */
  141. this.useAlbedoToTintTranslucency = false;
  142. this._thicknessTexture = null;
  143. /**
  144. * Stores the average thickness of a mesh in a texture (The texture is holding the values linearly).
  145. * The red (or green if useGltfStyleTextures=true) channel of the texture should contain the thickness remapped between 0 and 1.
  146. * 0 would mean minimumThickness
  147. * 1 would mean maximumThickness
  148. * The other channels might be use as a mask to vary the different effects intensity.
  149. */
  150. this.thicknessTexture = null;
  151. this._refractionTexture = null;
  152. /**
  153. * Defines the texture to use for refraction.
  154. */
  155. this.refractionTexture = null;
  156. /** @internal */
  157. this._indexOfRefraction = 1.5;
  158. /**
  159. * Index of refraction of the material base layer.
  160. * https://en.wikipedia.org/wiki/List_of_refractive_indices
  161. *
  162. * This does not only impact refraction but also the Base F0 of Dielectric Materials.
  163. *
  164. * From dielectric fresnel rules: F0 = square((iorT - iorI) / (iorT + iorI))
  165. */
  166. this.indexOfRefraction = 1.5;
  167. this._volumeIndexOfRefraction = -1.0;
  168. this._invertRefractionY = false;
  169. /**
  170. * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
  171. */
  172. this.invertRefractionY = false;
  173. /** @internal */
  174. this._linkRefractionWithTransparency = false;
  175. /**
  176. * This parameters will make the material used its opacity to control how much it is refracting against not.
  177. * Materials half opaque for instance using refraction could benefit from this control.
  178. */
  179. this.linkRefractionWithTransparency = false;
  180. /**
  181. * Defines the minimum thickness stored in the thickness map.
  182. * If no thickness map is defined, this value will be used to simulate thickness.
  183. */
  184. this.minimumThickness = 0;
  185. /**
  186. * Defines the maximum thickness stored in the thickness map.
  187. */
  188. this.maximumThickness = 1;
  189. /**
  190. * Defines that the thickness should be used as a measure of the depth volume.
  191. */
  192. this.useThicknessAsDepth = false;
  193. /**
  194. * Defines the volume tint of the material.
  195. * This is used for both translucency and scattering.
  196. */
  197. this.tintColor = Color3.White();
  198. /**
  199. * Defines the distance at which the tint color should be found in the media.
  200. * This is used for refraction only.
  201. */
  202. this.tintColorAtDistance = 1;
  203. /**
  204. * Defines the Abbe number for the volume.
  205. */
  206. this.dispersion = 0;
  207. /**
  208. * Defines how far each channel transmit through the media.
  209. * It is defined as a color to simplify it selection.
  210. */
  211. this.diffusionDistance = Color3.White();
  212. this._useMaskFromThicknessTexture = false;
  213. /**
  214. * Stores the intensity of the different subsurface effects in the thickness texture.
  215. * Note that if refractionIntensityTexture and/or translucencyIntensityTexture is provided it takes precedence over thicknessTexture + useMaskFromThicknessTexture
  216. * * the green (red if useGltfStyleTextures = true) channel is the refraction intensity.
  217. * * the blue channel is the translucency intensity.
  218. */
  219. this.useMaskFromThicknessTexture = false;
  220. this._refractionIntensityTexture = null;
  221. /**
  222. * Stores the intensity of the refraction. If provided, it takes precedence over thicknessTexture + useMaskFromThicknessTexture
  223. * * the green (red if useGltfStyleTextures = true) channel is the refraction intensity.
  224. */
  225. this.refractionIntensityTexture = null;
  226. this._translucencyIntensityTexture = null;
  227. /**
  228. * Stores the intensity of the translucency. If provided, it takes precedence over thicknessTexture + useMaskFromThicknessTexture
  229. * * the blue channel is the translucency intensity.
  230. */
  231. this.translucencyIntensityTexture = null;
  232. this._useGltfStyleTextures = false;
  233. /**
  234. * Use channels layout used by glTF:
  235. * * thicknessTexture: the green (instead of red) channel is the thickness
  236. * * thicknessTexture/refractionIntensityTexture: the red (instead of green) channel is the refraction intensity
  237. * * thicknessTexture/translucencyIntensityTexture: no change, use the blue channel for the translucency intensity
  238. */
  239. this.useGltfStyleTextures = false;
  240. this._scene = material.getScene();
  241. this.registerForExtraEvents = true;
  242. this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[1];
  243. this._internalMarkScenePrePassDirty = material._dirtyCallbacks[32];
  244. }
  245. isReadyForSubMesh(defines, scene) {
  246. if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {
  247. return true;
  248. }
  249. if (defines._areTexturesDirty) {
  250. if (scene.texturesEnabled) {
  251. if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {
  252. if (!this._thicknessTexture.isReadyOrNotBlocking()) {
  253. return false;
  254. }
  255. }
  256. const refractionTexture = this._getRefractionTexture(scene);
  257. if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {
  258. if (!refractionTexture.isReadyOrNotBlocking()) {
  259. return false;
  260. }
  261. }
  262. }
  263. }
  264. return true;
  265. }
  266. prepareDefinesBeforeAttributes(defines, scene) {
  267. if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {
  268. defines.SUBSURFACE = false;
  269. defines.SS_DISPERSION = false;
  270. defines.SS_TRANSLUCENCY = false;
  271. defines.SS_SCATTERING = false;
  272. defines.SS_REFRACTION = false;
  273. defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;
  274. defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;
  275. defines.SS_THICKNESSANDMASK_TEXTURE = false;
  276. defines.SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;
  277. defines.SS_HAS_THICKNESS = false;
  278. defines.SS_REFRACTIONINTENSITY_TEXTURE = false;
  279. defines.SS_REFRACTIONINTENSITY_TEXTUREDIRECTUV = 0;
  280. defines.SS_TRANSLUCENCYINTENSITY_TEXTURE = false;
  281. defines.SS_TRANSLUCENCYINTENSITY_TEXTUREDIRECTUV = 0;
  282. defines.SS_REFRACTIONMAP_3D = false;
  283. defines.SS_REFRACTIONMAP_OPPOSITEZ = false;
  284. defines.SS_LODINREFRACTIONALPHA = false;
  285. defines.SS_GAMMAREFRACTION = false;
  286. defines.SS_RGBDREFRACTION = false;
  287. defines.SS_LINEARSPECULARREFRACTION = false;
  288. defines.SS_LINKREFRACTIONTOTRANSPARENCY = false;
  289. defines.SS_ALBEDOFORREFRACTIONTINT = false;
  290. defines.SS_ALBEDOFORTRANSLUCENCYTINT = false;
  291. defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;
  292. defines.SS_USE_THICKNESS_AS_DEPTH = false;
  293. defines.SS_USE_GLTF_TEXTURES = false;
  294. return;
  295. }
  296. if (defines._areTexturesDirty) {
  297. defines.SUBSURFACE = true;
  298. defines.SS_DISPERSION = this._isDispersionEnabled;
  299. defines.SS_TRANSLUCENCY = this._isTranslucencyEnabled;
  300. defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = false;
  301. defines.SS_SCATTERING = this._isScatteringEnabled;
  302. defines.SS_THICKNESSANDMASK_TEXTURE = false;
  303. defines.SS_REFRACTIONINTENSITY_TEXTURE = false;
  304. defines.SS_TRANSLUCENCYINTENSITY_TEXTURE = false;
  305. defines.SS_HAS_THICKNESS = false;
  306. defines.SS_USE_GLTF_TEXTURES = false;
  307. defines.SS_REFRACTION = false;
  308. defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = false;
  309. defines.SS_REFRACTIONMAP_3D = false;
  310. defines.SS_GAMMAREFRACTION = false;
  311. defines.SS_RGBDREFRACTION = false;
  312. defines.SS_LINEARSPECULARREFRACTION = false;
  313. defines.SS_REFRACTIONMAP_OPPOSITEZ = false;
  314. defines.SS_LODINREFRACTIONALPHA = false;
  315. defines.SS_LINKREFRACTIONTOTRANSPARENCY = false;
  316. defines.SS_ALBEDOFORREFRACTIONTINT = false;
  317. defines.SS_ALBEDOFORTRANSLUCENCYTINT = false;
  318. defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = false;
  319. defines.SS_USE_THICKNESS_AS_DEPTH = false;
  320. if (defines._areTexturesDirty) {
  321. if (scene.texturesEnabled) {
  322. if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {
  323. PrepareDefinesForMergedUV(this._thicknessTexture, defines, "SS_THICKNESSANDMASK_TEXTURE");
  324. }
  325. if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled) {
  326. PrepareDefinesForMergedUV(this._refractionIntensityTexture, defines, "SS_REFRACTIONINTENSITY_TEXTURE");
  327. }
  328. if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled) {
  329. PrepareDefinesForMergedUV(this._translucencyIntensityTexture, defines, "SS_TRANSLUCENCYINTENSITY_TEXTURE");
  330. }
  331. }
  332. }
  333. defines.SS_HAS_THICKNESS = this.maximumThickness - this.minimumThickness !== 0.0;
  334. defines.SS_USE_GLTF_TEXTURES = this._useGltfStyleTextures;
  335. defines.SS_REFRACTION_USE_INTENSITY_FROM_THICKNESS = this._useMaskFromThicknessTexture && !this._refractionIntensityTexture;
  336. defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_THICKNESS = this._useMaskFromThicknessTexture && !this._translucencyIntensityTexture;
  337. if (this._isRefractionEnabled) {
  338. if (scene.texturesEnabled) {
  339. const refractionTexture = this._getRefractionTexture(scene);
  340. if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {
  341. defines.SS_REFRACTION = true;
  342. defines.SS_REFRACTIONMAP_3D = refractionTexture.isCube;
  343. defines.SS_GAMMAREFRACTION = refractionTexture.gammaSpace;
  344. defines.SS_RGBDREFRACTION = refractionTexture.isRGBD;
  345. defines.SS_LINEARSPECULARREFRACTION = refractionTexture.linearSpecularLOD;
  346. defines.SS_REFRACTIONMAP_OPPOSITEZ = this._scene.useRightHandedSystem && refractionTexture.isCube ? !refractionTexture.invertZ : refractionTexture.invertZ;
  347. defines.SS_LODINREFRACTIONALPHA = refractionTexture.lodLevelInAlpha;
  348. defines.SS_LINKREFRACTIONTOTRANSPARENCY = this._linkRefractionWithTransparency;
  349. defines.SS_ALBEDOFORREFRACTIONTINT = this.useAlbedoToTintRefraction;
  350. defines.SS_USE_LOCAL_REFRACTIONMAP_CUBIC = refractionTexture.isCube && refractionTexture.boundingBoxSize;
  351. defines.SS_USE_THICKNESS_AS_DEPTH = this.useThicknessAsDepth;
  352. }
  353. }
  354. }
  355. if (this._isTranslucencyEnabled) {
  356. defines.SS_ALBEDOFORTRANSLUCENCYTINT = this.useAlbedoToTintTranslucency;
  357. }
  358. }
  359. }
  360. /**
  361. * Binds the material data (this function is called even if mustRebind() returns false)
  362. * @param uniformBuffer defines the Uniform buffer to fill in.
  363. * @param scene defines the scene the material belongs to.
  364. * @param engine defines the engine the material belongs to.
  365. * @param subMesh the submesh to bind data for
  366. */
  367. hardBindForSubMesh(uniformBuffer, scene, engine, subMesh) {
  368. if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {
  369. return;
  370. }
  371. subMesh.getRenderingMesh().getWorldMatrix().decompose(TmpVectors.Vector3[0]);
  372. const thicknessScale = Math.max(Math.abs(TmpVectors.Vector3[0].x), Math.abs(TmpVectors.Vector3[0].y), Math.abs(TmpVectors.Vector3[0].z));
  373. uniformBuffer.updateFloat2("vThicknessParam", this.minimumThickness * thicknessScale, (this.maximumThickness - this.minimumThickness) * thicknessScale);
  374. }
  375. bindForSubMesh(uniformBuffer, scene, engine, subMesh) {
  376. if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {
  377. return;
  378. }
  379. const defines = subMesh.materialDefines;
  380. const isFrozen = this._material.isFrozen;
  381. const realTimeFiltering = this._material.realTimeFiltering;
  382. const lodBasedMicrosurface = defines.LODBASEDMICROSFURACE;
  383. const refractionTexture = this._getRefractionTexture(scene);
  384. if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
  385. if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {
  386. uniformBuffer.updateFloat2("vThicknessInfos", this._thicknessTexture.coordinatesIndex, this._thicknessTexture.level);
  387. BindTextureMatrix(this._thicknessTexture, uniformBuffer, "thickness");
  388. }
  389. if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled && defines.SS_REFRACTIONINTENSITY_TEXTURE) {
  390. uniformBuffer.updateFloat2("vRefractionIntensityInfos", this._refractionIntensityTexture.coordinatesIndex, this._refractionIntensityTexture.level);
  391. BindTextureMatrix(this._refractionIntensityTexture, uniformBuffer, "refractionIntensity");
  392. }
  393. if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled && defines.SS_TRANSLUCENCYINTENSITY_TEXTURE) {
  394. uniformBuffer.updateFloat2("vTranslucencyIntensityInfos", this._translucencyIntensityTexture.coordinatesIndex, this._translucencyIntensityTexture.level);
  395. BindTextureMatrix(this._translucencyIntensityTexture, uniformBuffer, "translucencyIntensity");
  396. }
  397. if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {
  398. uniformBuffer.updateMatrix("refractionMatrix", refractionTexture.getRefractionTextureMatrix());
  399. let depth = 1.0;
  400. if (!refractionTexture.isCube) {
  401. if (refractionTexture.depth) {
  402. depth = refractionTexture.depth;
  403. }
  404. }
  405. const width = refractionTexture.getSize().width;
  406. const refractionIor = this.volumeIndexOfRefraction;
  407. uniformBuffer.updateFloat4("vRefractionInfos", refractionTexture.level, 1 / refractionIor, depth, this._invertRefractionY ? -1 : 1);
  408. uniformBuffer.updateFloat4("vRefractionMicrosurfaceInfos", width, refractionTexture.lodGenerationScale, refractionTexture.lodGenerationOffset, 1.0 / this.indexOfRefraction);
  409. if (realTimeFiltering) {
  410. uniformBuffer.updateFloat2("vRefractionFilteringInfo", width, Scalar.Log2(width));
  411. }
  412. if (refractionTexture.boundingBoxSize) {
  413. const cubeTexture = refractionTexture;
  414. uniformBuffer.updateVector3("vRefractionPosition", cubeTexture.boundingBoxPosition);
  415. uniformBuffer.updateVector3("vRefractionSize", cubeTexture.boundingBoxSize);
  416. }
  417. }
  418. if (this._isScatteringEnabled) {
  419. uniformBuffer.updateFloat("scatteringDiffusionProfile", this._scatteringDiffusionProfileIndex);
  420. }
  421. uniformBuffer.updateColor3("vDiffusionDistance", this.diffusionDistance);
  422. uniformBuffer.updateFloat4("vTintColor", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintColorAtDistance));
  423. uniformBuffer.updateFloat3("vSubSurfaceIntensity", this.refractionIntensity, this.translucencyIntensity, 0);
  424. uniformBuffer.updateFloat("dispersion", this.dispersion);
  425. }
  426. // Textures
  427. if (scene.texturesEnabled) {
  428. if (this._thicknessTexture && MaterialFlags.ThicknessTextureEnabled) {
  429. uniformBuffer.setTexture("thicknessSampler", this._thicknessTexture);
  430. }
  431. if (this._refractionIntensityTexture && MaterialFlags.RefractionIntensityTextureEnabled && defines.SS_REFRACTIONINTENSITY_TEXTURE) {
  432. uniformBuffer.setTexture("refractionIntensitySampler", this._refractionIntensityTexture);
  433. }
  434. if (this._translucencyIntensityTexture && MaterialFlags.TranslucencyIntensityTextureEnabled && defines.SS_TRANSLUCENCYINTENSITY_TEXTURE) {
  435. uniformBuffer.setTexture("translucencyIntensitySampler", this._translucencyIntensityTexture);
  436. }
  437. if (refractionTexture && MaterialFlags.RefractionTextureEnabled) {
  438. if (lodBasedMicrosurface) {
  439. uniformBuffer.setTexture("refractionSampler", refractionTexture);
  440. }
  441. else {
  442. uniformBuffer.setTexture("refractionSampler", refractionTexture._lodTextureMid || refractionTexture);
  443. uniformBuffer.setTexture("refractionSamplerLow", refractionTexture._lodTextureLow || refractionTexture);
  444. uniformBuffer.setTexture("refractionSamplerHigh", refractionTexture._lodTextureHigh || refractionTexture);
  445. }
  446. }
  447. }
  448. }
  449. /**
  450. * Returns the texture used for refraction or null if none is used.
  451. * @param scene defines the scene the material belongs to.
  452. * @returns - Refraction texture if present. If no refraction texture and refraction
  453. * is linked with transparency, returns environment texture. Otherwise, returns null.
  454. */
  455. _getRefractionTexture(scene) {
  456. if (this._refractionTexture) {
  457. return this._refractionTexture;
  458. }
  459. if (this._isRefractionEnabled) {
  460. return scene.environmentTexture;
  461. }
  462. return null;
  463. }
  464. /**
  465. * Returns true if alpha blending should be disabled.
  466. */
  467. get disableAlphaBlending() {
  468. return this._isRefractionEnabled && this._linkRefractionWithTransparency;
  469. }
  470. /**
  471. * Fills the list of render target textures.
  472. * @param renderTargets the list of render targets to update
  473. */
  474. fillRenderTargetTextures(renderTargets) {
  475. if (MaterialFlags.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
  476. renderTargets.push(this._refractionTexture);
  477. }
  478. }
  479. hasTexture(texture) {
  480. if (this._thicknessTexture === texture) {
  481. return true;
  482. }
  483. if (this._refractionTexture === texture) {
  484. return true;
  485. }
  486. if (this._refractionIntensityTexture === texture) {
  487. return true;
  488. }
  489. if (this._translucencyIntensityTexture === texture) {
  490. return true;
  491. }
  492. return false;
  493. }
  494. hasRenderTargetTextures() {
  495. if (MaterialFlags.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
  496. return true;
  497. }
  498. return false;
  499. }
  500. getActiveTextures(activeTextures) {
  501. if (this._thicknessTexture) {
  502. activeTextures.push(this._thicknessTexture);
  503. }
  504. if (this._refractionTexture) {
  505. activeTextures.push(this._refractionTexture);
  506. }
  507. }
  508. getAnimatables(animatables) {
  509. if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) {
  510. animatables.push(this._thicknessTexture);
  511. }
  512. if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {
  513. animatables.push(this._refractionTexture);
  514. }
  515. }
  516. dispose(forceDisposeTextures) {
  517. if (forceDisposeTextures) {
  518. if (this._thicknessTexture) {
  519. this._thicknessTexture.dispose();
  520. }
  521. if (this._refractionTexture) {
  522. this._refractionTexture.dispose();
  523. }
  524. }
  525. }
  526. getClassName() {
  527. return "PBRSubSurfaceConfiguration";
  528. }
  529. addFallbacks(defines, fallbacks, currentRank) {
  530. if (defines.SS_SCATTERING) {
  531. fallbacks.addFallback(currentRank++, "SS_SCATTERING");
  532. }
  533. if (defines.SS_TRANSLUCENCY) {
  534. fallbacks.addFallback(currentRank++, "SS_TRANSLUCENCY");
  535. }
  536. return currentRank;
  537. }
  538. getSamplers(samplers) {
  539. samplers.push("thicknessSampler", "refractionIntensitySampler", "translucencyIntensitySampler", "refractionSampler", "refractionSamplerLow", "refractionSamplerHigh");
  540. }
  541. getUniforms() {
  542. return {
  543. ubo: [
  544. { name: "vRefractionMicrosurfaceInfos", size: 4, type: "vec4" },
  545. { name: "vRefractionFilteringInfo", size: 2, type: "vec2" },
  546. { name: "vTranslucencyIntensityInfos", size: 2, type: "vec2" },
  547. { name: "vRefractionInfos", size: 4, type: "vec4" },
  548. { name: "refractionMatrix", size: 16, type: "mat4" },
  549. { name: "vThicknessInfos", size: 2, type: "vec2" },
  550. { name: "vRefractionIntensityInfos", size: 2, type: "vec2" },
  551. { name: "thicknessMatrix", size: 16, type: "mat4" },
  552. { name: "refractionIntensityMatrix", size: 16, type: "mat4" },
  553. { name: "translucencyIntensityMatrix", size: 16, type: "mat4" },
  554. { name: "vThicknessParam", size: 2, type: "vec2" },
  555. { name: "vDiffusionDistance", size: 3, type: "vec3" },
  556. { name: "vTintColor", size: 4, type: "vec4" },
  557. { name: "vSubSurfaceIntensity", size: 3, type: "vec3" },
  558. { name: "vRefractionPosition", size: 3, type: "vec3" },
  559. { name: "vRefractionSize", size: 3, type: "vec3" },
  560. { name: "scatteringDiffusionProfile", size: 1, type: "float" },
  561. { name: "dispersion", size: 1, type: "float" },
  562. ],
  563. };
  564. }
  565. }
  566. __decorate([
  567. serialize(),
  568. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  569. ], PBRSubSurfaceConfiguration.prototype, "isRefractionEnabled", void 0);
  570. __decorate([
  571. serialize(),
  572. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  573. ], PBRSubSurfaceConfiguration.prototype, "isTranslucencyEnabled", void 0);
  574. __decorate([
  575. serialize(),
  576. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  577. ], PBRSubSurfaceConfiguration.prototype, "isDispersionEnabled", void 0);
  578. __decorate([
  579. serialize(),
  580. expandToProperty("_markScenePrePassDirty")
  581. ], PBRSubSurfaceConfiguration.prototype, "isScatteringEnabled", void 0);
  582. __decorate([
  583. serialize()
  584. ], PBRSubSurfaceConfiguration.prototype, "_scatteringDiffusionProfileIndex", void 0);
  585. __decorate([
  586. serialize()
  587. ], PBRSubSurfaceConfiguration.prototype, "refractionIntensity", void 0);
  588. __decorate([
  589. serialize()
  590. ], PBRSubSurfaceConfiguration.prototype, "translucencyIntensity", void 0);
  591. __decorate([
  592. serialize()
  593. ], PBRSubSurfaceConfiguration.prototype, "useAlbedoToTintRefraction", void 0);
  594. __decorate([
  595. serialize()
  596. ], PBRSubSurfaceConfiguration.prototype, "useAlbedoToTintTranslucency", void 0);
  597. __decorate([
  598. serializeAsTexture(),
  599. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  600. ], PBRSubSurfaceConfiguration.prototype, "thicknessTexture", void 0);
  601. __decorate([
  602. serializeAsTexture(),
  603. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  604. ], PBRSubSurfaceConfiguration.prototype, "refractionTexture", void 0);
  605. __decorate([
  606. serialize(),
  607. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  608. ], PBRSubSurfaceConfiguration.prototype, "indexOfRefraction", void 0);
  609. __decorate([
  610. serialize()
  611. ], PBRSubSurfaceConfiguration.prototype, "_volumeIndexOfRefraction", void 0);
  612. __decorate([
  613. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  614. ], PBRSubSurfaceConfiguration.prototype, "volumeIndexOfRefraction", null);
  615. __decorate([
  616. serialize(),
  617. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  618. ], PBRSubSurfaceConfiguration.prototype, "invertRefractionY", void 0);
  619. __decorate([
  620. serialize(),
  621. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  622. ], PBRSubSurfaceConfiguration.prototype, "linkRefractionWithTransparency", void 0);
  623. __decorate([
  624. serialize()
  625. ], PBRSubSurfaceConfiguration.prototype, "minimumThickness", void 0);
  626. __decorate([
  627. serialize()
  628. ], PBRSubSurfaceConfiguration.prototype, "maximumThickness", void 0);
  629. __decorate([
  630. serialize()
  631. ], PBRSubSurfaceConfiguration.prototype, "useThicknessAsDepth", void 0);
  632. __decorate([
  633. serializeAsColor3()
  634. ], PBRSubSurfaceConfiguration.prototype, "tintColor", void 0);
  635. __decorate([
  636. serialize()
  637. ], PBRSubSurfaceConfiguration.prototype, "tintColorAtDistance", void 0);
  638. __decorate([
  639. serialize()
  640. ], PBRSubSurfaceConfiguration.prototype, "dispersion", void 0);
  641. __decorate([
  642. serializeAsColor3()
  643. ], PBRSubSurfaceConfiguration.prototype, "diffusionDistance", void 0);
  644. __decorate([
  645. serialize(),
  646. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  647. ], PBRSubSurfaceConfiguration.prototype, "useMaskFromThicknessTexture", void 0);
  648. __decorate([
  649. serializeAsTexture(),
  650. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  651. ], PBRSubSurfaceConfiguration.prototype, "refractionIntensityTexture", void 0);
  652. __decorate([
  653. serializeAsTexture(),
  654. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  655. ], PBRSubSurfaceConfiguration.prototype, "translucencyIntensityTexture", void 0);
  656. __decorate([
  657. serialize(),
  658. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  659. ], PBRSubSurfaceConfiguration.prototype, "useGltfStyleTextures", void 0);
  660. //# sourceMappingURL=pbrSubSurfaceConfiguration.js.map