pbrAnisotropicConfiguration.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { __decorate } from "../../tslib.es6.js";
  2. /* eslint-disable @typescript-eslint/naming-convention */
  3. import { serialize, expandToProperty, serializeAsVector2, serializeAsTexture } from "../../Misc/decorators.js";
  4. import { VertexBuffer } from "../../Buffers/buffer.js";
  5. import { Vector2 } from "../../Maths/math.vector.js";
  6. import { MaterialFlags } from "../../Materials/materialFlags.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 MaterialAnisotropicDefines extends MaterialDefines {
  14. constructor() {
  15. super(...arguments);
  16. this.ANISOTROPIC = false;
  17. this.ANISOTROPIC_TEXTURE = false;
  18. this.ANISOTROPIC_TEXTUREDIRECTUV = 0;
  19. this.ANISOTROPIC_LEGACY = false;
  20. this.MAINUV1 = false;
  21. }
  22. }
  23. /**
  24. * Plugin that implements the anisotropic component of the PBR material
  25. */
  26. export class PBRAnisotropicConfiguration extends MaterialPluginBase {
  27. /**
  28. * Sets the anisotropy direction as an angle.
  29. */
  30. set angle(value) {
  31. this.direction.x = Math.cos(value);
  32. this.direction.y = Math.sin(value);
  33. }
  34. /**
  35. * Gets the anisotropy angle value in radians.
  36. * @returns the anisotropy angle value in radians.
  37. */
  38. get angle() {
  39. return Math.atan2(this.direction.y, this.direction.x);
  40. }
  41. /** @internal */
  42. _markAllSubMeshesAsTexturesDirty() {
  43. this._enable(this._isEnabled);
  44. this._internalMarkAllSubMeshesAsTexturesDirty();
  45. }
  46. /** @internal */
  47. _markAllSubMeshesAsMiscDirty() {
  48. this._enable(this._isEnabled);
  49. this._internalMarkAllSubMeshesAsMiscDirty();
  50. }
  51. constructor(material, addToPluginList = true) {
  52. super(material, "PBRAnisotropic", 110, new MaterialAnisotropicDefines(), addToPluginList);
  53. this._isEnabled = false;
  54. /**
  55. * Defines if the anisotropy is enabled in the material.
  56. */
  57. this.isEnabled = false;
  58. /**
  59. * Defines the anisotropy strength (between 0 and 1) it defaults to 1.
  60. */
  61. this.intensity = 1;
  62. /**
  63. * Defines if the effect is along the tangents, bitangents or in between.
  64. * By default, the effect is "stretching" the highlights along the tangents.
  65. */
  66. this.direction = new Vector2(1, 0);
  67. this._texture = null;
  68. /**
  69. * Stores the anisotropy values in a texture.
  70. * rg is direction (like normal from -1 to 1)
  71. * b is a intensity
  72. */
  73. this.texture = null;
  74. this._legacy = false;
  75. /**
  76. * Defines if the anisotropy is in legacy mode for backwards compatibility before 6.4.0.
  77. */
  78. this.legacy = false;
  79. this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[1];
  80. this._internalMarkAllSubMeshesAsMiscDirty = material._dirtyCallbacks[16];
  81. }
  82. isReadyForSubMesh(defines, scene) {
  83. if (!this._isEnabled) {
  84. return true;
  85. }
  86. if (defines._areTexturesDirty) {
  87. if (scene.texturesEnabled) {
  88. if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {
  89. if (!this._texture.isReadyOrNotBlocking()) {
  90. return false;
  91. }
  92. }
  93. }
  94. }
  95. return true;
  96. }
  97. prepareDefinesBeforeAttributes(defines, scene, mesh) {
  98. if (this._isEnabled) {
  99. defines.ANISOTROPIC = this._isEnabled;
  100. if (this._isEnabled && !mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
  101. defines._needUVs = true;
  102. defines.MAINUV1 = true;
  103. }
  104. if (defines._areTexturesDirty) {
  105. if (scene.texturesEnabled) {
  106. if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {
  107. PrepareDefinesForMergedUV(this._texture, defines, "ANISOTROPIC_TEXTURE");
  108. }
  109. else {
  110. defines.ANISOTROPIC_TEXTURE = false;
  111. }
  112. }
  113. }
  114. if (defines._areMiscDirty) {
  115. defines.ANISOTROPIC_LEGACY = this._legacy;
  116. }
  117. }
  118. else {
  119. defines.ANISOTROPIC = false;
  120. defines.ANISOTROPIC_TEXTURE = false;
  121. defines.ANISOTROPIC_TEXTUREDIRECTUV = 0;
  122. defines.ANISOTROPIC_LEGACY = false;
  123. }
  124. }
  125. bindForSubMesh(uniformBuffer, scene) {
  126. if (!this._isEnabled) {
  127. return;
  128. }
  129. const isFrozen = this._material.isFrozen;
  130. if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
  131. if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {
  132. uniformBuffer.updateFloat2("vAnisotropyInfos", this._texture.coordinatesIndex, this._texture.level);
  133. BindTextureMatrix(this._texture, uniformBuffer, "anisotropy");
  134. }
  135. // Anisotropy
  136. uniformBuffer.updateFloat3("vAnisotropy", this.direction.x, this.direction.y, this.intensity);
  137. }
  138. // Textures
  139. if (scene.texturesEnabled) {
  140. if (this._texture && MaterialFlags.AnisotropicTextureEnabled) {
  141. uniformBuffer.setTexture("anisotropySampler", this._texture);
  142. }
  143. }
  144. }
  145. hasTexture(texture) {
  146. if (this._texture === texture) {
  147. return true;
  148. }
  149. return false;
  150. }
  151. getActiveTextures(activeTextures) {
  152. if (this._texture) {
  153. activeTextures.push(this._texture);
  154. }
  155. }
  156. getAnimatables(animatables) {
  157. if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
  158. animatables.push(this._texture);
  159. }
  160. }
  161. dispose(forceDisposeTextures) {
  162. if (forceDisposeTextures) {
  163. if (this._texture) {
  164. this._texture.dispose();
  165. }
  166. }
  167. }
  168. getClassName() {
  169. return "PBRAnisotropicConfiguration";
  170. }
  171. addFallbacks(defines, fallbacks, currentRank) {
  172. if (defines.ANISOTROPIC) {
  173. fallbacks.addFallback(currentRank++, "ANISOTROPIC");
  174. }
  175. return currentRank;
  176. }
  177. getSamplers(samplers) {
  178. samplers.push("anisotropySampler");
  179. }
  180. getUniforms() {
  181. return {
  182. ubo: [
  183. { name: "vAnisotropy", size: 3, type: "vec3" },
  184. { name: "vAnisotropyInfos", size: 2, type: "vec2" },
  185. { name: "anisotropyMatrix", size: 16, type: "mat4" },
  186. ],
  187. };
  188. }
  189. /**
  190. * Parses a anisotropy Configuration from a serialized object.
  191. * @param source - Serialized object.
  192. * @param scene Defines the scene we are parsing for
  193. * @param rootUrl Defines the rootUrl to load from
  194. */
  195. parse(source, scene, rootUrl) {
  196. super.parse(source, scene, rootUrl);
  197. // Backward compatibility
  198. if (source.legacy === undefined) {
  199. this.legacy = true;
  200. }
  201. }
  202. }
  203. __decorate([
  204. serialize(),
  205. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  206. ], PBRAnisotropicConfiguration.prototype, "isEnabled", void 0);
  207. __decorate([
  208. serialize()
  209. ], PBRAnisotropicConfiguration.prototype, "intensity", void 0);
  210. __decorate([
  211. serializeAsVector2()
  212. ], PBRAnisotropicConfiguration.prototype, "direction", void 0);
  213. __decorate([
  214. serializeAsTexture(),
  215. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  216. ], PBRAnisotropicConfiguration.prototype, "texture", void 0);
  217. __decorate([
  218. serialize(),
  219. expandToProperty("_markAllSubMeshesAsMiscDirty")
  220. ], PBRAnisotropicConfiguration.prototype, "legacy", void 0);
  221. //# sourceMappingURL=pbrAnisotropicConfiguration.js.map