pbrIridescenceConfiguration.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import { __decorate } from "../../tslib.es6.js";
  2. import { serialize, serializeAsTexture, expandToProperty } from "../../Misc/decorators.js";
  3. import { MaterialFlags } from "../materialFlags.js";
  4. import { MaterialPluginBase } from "../materialPluginBase.js";
  5. import { MaterialDefines } from "../materialDefines.js";
  6. import { BindTextureMatrix, PrepareDefinesForMergedUV } from "../materialHelper.functions.js";
  7. /**
  8. * @internal
  9. */
  10. export class MaterialIridescenceDefines extends MaterialDefines {
  11. constructor() {
  12. super(...arguments);
  13. this.IRIDESCENCE = false;
  14. this.IRIDESCENCE_TEXTURE = false;
  15. this.IRIDESCENCE_TEXTUREDIRECTUV = 0;
  16. this.IRIDESCENCE_THICKNESS_TEXTURE = false;
  17. this.IRIDESCENCE_THICKNESS_TEXTUREDIRECTUV = 0;
  18. }
  19. }
  20. /**
  21. * Plugin that implements the iridescence (thin film) component of the PBR material
  22. */
  23. export class PBRIridescenceConfiguration extends MaterialPluginBase {
  24. /** @internal */
  25. _markAllSubMeshesAsTexturesDirty() {
  26. this._enable(this._isEnabled);
  27. this._internalMarkAllSubMeshesAsTexturesDirty();
  28. }
  29. constructor(material, addToPluginList = true) {
  30. super(material, "PBRIridescence", 110, new MaterialIridescenceDefines(), addToPluginList);
  31. this._isEnabled = false;
  32. /**
  33. * Defines if the iridescence is enabled in the material.
  34. */
  35. this.isEnabled = false;
  36. /**
  37. * Defines the iridescence layer strength (between 0 and 1) it defaults to 1.
  38. */
  39. this.intensity = 1;
  40. /**
  41. * Defines the minimum thickness of the thin-film layer given in nanometers (nm).
  42. */
  43. this.minimumThickness = PBRIridescenceConfiguration._DefaultMinimumThickness;
  44. /**
  45. * Defines the maximum thickness of the thin-film layer given in nanometers (nm). This will be the thickness used if not thickness texture has been set.
  46. */
  47. this.maximumThickness = PBRIridescenceConfiguration._DefaultMaximumThickness;
  48. /**
  49. * Defines the maximum thickness of the thin-film layer given in nanometers (nm).
  50. */
  51. this.indexOfRefraction = PBRIridescenceConfiguration._DefaultIndexOfRefraction;
  52. this._texture = null;
  53. /**
  54. * Stores the iridescence intensity in a texture (red channel)
  55. */
  56. this.texture = null;
  57. this._thicknessTexture = null;
  58. /**
  59. * Stores the iridescence thickness in a texture (green channel)
  60. */
  61. this.thicknessTexture = null;
  62. this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[1];
  63. }
  64. isReadyForSubMesh(defines, scene) {
  65. if (!this._isEnabled) {
  66. return true;
  67. }
  68. if (defines._areTexturesDirty) {
  69. if (scene.texturesEnabled) {
  70. if (this._texture && MaterialFlags.IridescenceTextureEnabled) {
  71. if (!this._texture.isReadyOrNotBlocking()) {
  72. return false;
  73. }
  74. }
  75. if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {
  76. if (!this._thicknessTexture.isReadyOrNotBlocking()) {
  77. return false;
  78. }
  79. }
  80. }
  81. }
  82. return true;
  83. }
  84. prepareDefinesBeforeAttributes(defines, scene) {
  85. if (this._isEnabled) {
  86. defines.IRIDESCENCE = true;
  87. if (defines._areTexturesDirty) {
  88. if (scene.texturesEnabled) {
  89. if (this._texture && MaterialFlags.IridescenceTextureEnabled) {
  90. PrepareDefinesForMergedUV(this._texture, defines, "IRIDESCENCE_TEXTURE");
  91. }
  92. else {
  93. defines.IRIDESCENCE_TEXTURE = false;
  94. }
  95. if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {
  96. PrepareDefinesForMergedUV(this._thicknessTexture, defines, "IRIDESCENCE_THICKNESS_TEXTURE");
  97. }
  98. else {
  99. defines.IRIDESCENCE_THICKNESS_TEXTURE = false;
  100. }
  101. }
  102. }
  103. }
  104. else {
  105. defines.IRIDESCENCE = false;
  106. defines.IRIDESCENCE_TEXTURE = false;
  107. defines.IRIDESCENCE_THICKNESS_TEXTURE = false;
  108. defines.IRIDESCENCE_TEXTUREDIRECTUV = 0;
  109. defines.IRIDESCENCE_THICKNESS_TEXTUREDIRECTUV = 0;
  110. }
  111. }
  112. bindForSubMesh(uniformBuffer, scene) {
  113. if (!this._isEnabled) {
  114. return;
  115. }
  116. const isFrozen = this._material.isFrozen;
  117. if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
  118. if ((this._texture || this._thicknessTexture) && MaterialFlags.IridescenceTextureEnabled) {
  119. uniformBuffer.updateFloat4("vIridescenceInfos", this._texture?.coordinatesIndex ?? 0, this._texture?.level ?? 0, this._thicknessTexture?.coordinatesIndex ?? 0, this._thicknessTexture?.level ?? 0);
  120. if (this._texture) {
  121. BindTextureMatrix(this._texture, uniformBuffer, "iridescence");
  122. }
  123. if (this._thicknessTexture) {
  124. BindTextureMatrix(this._thicknessTexture, uniformBuffer, "iridescenceThickness");
  125. }
  126. }
  127. // Clear Coat General params
  128. uniformBuffer.updateFloat4("vIridescenceParams", this.intensity, this.indexOfRefraction, this.minimumThickness, this.maximumThickness);
  129. }
  130. // Textures
  131. if (scene.texturesEnabled) {
  132. if (this._texture && MaterialFlags.IridescenceTextureEnabled) {
  133. uniformBuffer.setTexture("iridescenceSampler", this._texture);
  134. }
  135. if (this._thicknessTexture && MaterialFlags.IridescenceTextureEnabled) {
  136. uniformBuffer.setTexture("iridescenceThicknessSampler", this._thicknessTexture);
  137. }
  138. }
  139. }
  140. hasTexture(texture) {
  141. if (this._texture === texture) {
  142. return true;
  143. }
  144. if (this._thicknessTexture === texture) {
  145. return true;
  146. }
  147. return false;
  148. }
  149. getActiveTextures(activeTextures) {
  150. if (this._texture) {
  151. activeTextures.push(this._texture);
  152. }
  153. if (this._thicknessTexture) {
  154. activeTextures.push(this._thicknessTexture);
  155. }
  156. }
  157. getAnimatables(animatables) {
  158. if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
  159. animatables.push(this._texture);
  160. }
  161. if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) {
  162. animatables.push(this._thicknessTexture);
  163. }
  164. }
  165. dispose(forceDisposeTextures) {
  166. if (forceDisposeTextures) {
  167. this._texture?.dispose();
  168. this._thicknessTexture?.dispose();
  169. }
  170. }
  171. getClassName() {
  172. return "PBRIridescenceConfiguration";
  173. }
  174. addFallbacks(defines, fallbacks, currentRank) {
  175. if (defines.IRIDESCENCE) {
  176. fallbacks.addFallback(currentRank++, "IRIDESCENCE");
  177. }
  178. return currentRank;
  179. }
  180. getSamplers(samplers) {
  181. samplers.push("iridescenceSampler", "iridescenceThicknessSampler");
  182. }
  183. getUniforms() {
  184. return {
  185. ubo: [
  186. { name: "vIridescenceParams", size: 4, type: "vec4" },
  187. { name: "vIridescenceInfos", size: 4, type: "vec4" },
  188. { name: "iridescenceMatrix", size: 16, type: "mat4" },
  189. { name: "iridescenceThicknessMatrix", size: 16, type: "mat4" },
  190. ],
  191. };
  192. }
  193. }
  194. /**
  195. * The default minimum thickness of the thin-film layer given in nanometers (nm).
  196. * Defaults to 100 nm.
  197. * @internal
  198. */
  199. PBRIridescenceConfiguration._DefaultMinimumThickness = 100;
  200. /**
  201. * The default maximum thickness of the thin-film layer given in nanometers (nm).
  202. * Defaults to 400 nm.
  203. * @internal
  204. */
  205. PBRIridescenceConfiguration._DefaultMaximumThickness = 400;
  206. /**
  207. * The default index of refraction of the thin-film layer.
  208. * Defaults to 1.3
  209. * @internal
  210. */
  211. PBRIridescenceConfiguration._DefaultIndexOfRefraction = 1.3;
  212. __decorate([
  213. serialize(),
  214. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  215. ], PBRIridescenceConfiguration.prototype, "isEnabled", void 0);
  216. __decorate([
  217. serialize()
  218. ], PBRIridescenceConfiguration.prototype, "intensity", void 0);
  219. __decorate([
  220. serialize()
  221. ], PBRIridescenceConfiguration.prototype, "minimumThickness", void 0);
  222. __decorate([
  223. serialize()
  224. ], PBRIridescenceConfiguration.prototype, "maximumThickness", void 0);
  225. __decorate([
  226. serialize()
  227. ], PBRIridescenceConfiguration.prototype, "indexOfRefraction", void 0);
  228. __decorate([
  229. serializeAsTexture(),
  230. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  231. ], PBRIridescenceConfiguration.prototype, "texture", void 0);
  232. __decorate([
  233. serializeAsTexture(),
  234. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  235. ], PBRIridescenceConfiguration.prototype, "thicknessTexture", void 0);
  236. //# sourceMappingURL=pbrIridescenceConfiguration.js.map