pbrSheenConfiguration.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import { __decorate } from "../../tslib.es6.js";
  2. /* eslint-disable @typescript-eslint/naming-convention */
  3. import { serialize, expandToProperty, serializeAsColor3, serializeAsTexture } from "../../Misc/decorators.js";
  4. import { Color3 } from "../../Maths/math.color.js";
  5. import { MaterialFlags } from "../../Materials/materialFlags.js";
  6. import { MaterialPluginBase } from "../materialPluginBase.js";
  7. import { MaterialDefines } from "../materialDefines.js";
  8. import { BindTextureMatrix, PrepareDefinesForMergedUV } from "../materialHelper.functions.js";
  9. /**
  10. * @internal
  11. */
  12. export class MaterialSheenDefines extends MaterialDefines {
  13. constructor() {
  14. super(...arguments);
  15. this.SHEEN = false;
  16. this.SHEEN_TEXTURE = false;
  17. this.SHEEN_GAMMATEXTURE = false;
  18. this.SHEEN_TEXTURE_ROUGHNESS = false;
  19. this.SHEEN_TEXTUREDIRECTUV = 0;
  20. this.SHEEN_TEXTURE_ROUGHNESSDIRECTUV = 0;
  21. this.SHEEN_LINKWITHALBEDO = false;
  22. this.SHEEN_ROUGHNESS = false;
  23. this.SHEEN_ALBEDOSCALING = false;
  24. this.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = false;
  25. }
  26. }
  27. /**
  28. * Plugin that implements the sheen component of the PBR material.
  29. */
  30. export class PBRSheenConfiguration extends MaterialPluginBase {
  31. /** @internal */
  32. _markAllSubMeshesAsTexturesDirty() {
  33. this._enable(this._isEnabled);
  34. this._internalMarkAllSubMeshesAsTexturesDirty();
  35. }
  36. constructor(material, addToPluginList = true) {
  37. super(material, "Sheen", 120, new MaterialSheenDefines(), addToPluginList);
  38. this._isEnabled = false;
  39. /**
  40. * Defines if the material uses sheen.
  41. */
  42. this.isEnabled = false;
  43. this._linkSheenWithAlbedo = false;
  44. /**
  45. * Defines if the sheen is linked to the sheen color.
  46. */
  47. this.linkSheenWithAlbedo = false;
  48. /**
  49. * Defines the sheen intensity.
  50. */
  51. this.intensity = 1;
  52. /**
  53. * Defines the sheen color.
  54. */
  55. this.color = Color3.White();
  56. this._texture = null;
  57. /**
  58. * Stores the sheen tint values in a texture.
  59. * rgb is tint
  60. * a is a intensity or roughness if the roughness property has been defined and useRoughnessFromTexture is true (in that case, textureRoughness won't be used)
  61. * If the roughness property has been defined and useRoughnessFromTexture is false then the alpha channel is not used to modulate roughness
  62. */
  63. this.texture = null;
  64. this._useRoughnessFromMainTexture = true;
  65. /**
  66. * Indicates that the alpha channel of the texture property will be used for roughness.
  67. * Has no effect if the roughness (and texture!) property is not defined
  68. */
  69. this.useRoughnessFromMainTexture = true;
  70. this._roughness = null;
  71. /**
  72. * Defines the sheen roughness.
  73. * It is not taken into account if linkSheenWithAlbedo is true.
  74. * To stay backward compatible, material roughness is used instead if sheen roughness = null
  75. */
  76. this.roughness = null;
  77. this._textureRoughness = null;
  78. /**
  79. * Stores the sheen roughness in a texture.
  80. * alpha channel is the roughness. This texture won't be used if the texture property is not empty and useRoughnessFromTexture is true
  81. */
  82. this.textureRoughness = null;
  83. this._albedoScaling = false;
  84. /**
  85. * If true, the sheen effect is layered above the base BRDF with the albedo-scaling technique.
  86. * It allows the strength of the sheen effect to not depend on the base color of the material,
  87. * making it easier to setup and tweak the effect
  88. */
  89. this.albedoScaling = false;
  90. this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[1];
  91. }
  92. isReadyForSubMesh(defines, scene) {
  93. if (!this._isEnabled) {
  94. return true;
  95. }
  96. if (defines._areTexturesDirty) {
  97. if (scene.texturesEnabled) {
  98. if (this._texture && MaterialFlags.SheenTextureEnabled) {
  99. if (!this._texture.isReadyOrNotBlocking()) {
  100. return false;
  101. }
  102. }
  103. if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
  104. if (!this._textureRoughness.isReadyOrNotBlocking()) {
  105. return false;
  106. }
  107. }
  108. }
  109. }
  110. return true;
  111. }
  112. prepareDefinesBeforeAttributes(defines, scene) {
  113. if (this._isEnabled) {
  114. defines.SHEEN = true;
  115. defines.SHEEN_LINKWITHALBEDO = this._linkSheenWithAlbedo;
  116. defines.SHEEN_ROUGHNESS = this._roughness !== null;
  117. defines.SHEEN_ALBEDOSCALING = this._albedoScaling;
  118. defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = this._useRoughnessFromMainTexture;
  119. if (defines._areTexturesDirty) {
  120. if (scene.texturesEnabled) {
  121. if (this._texture && MaterialFlags.SheenTextureEnabled) {
  122. PrepareDefinesForMergedUV(this._texture, defines, "SHEEN_TEXTURE");
  123. defines.SHEEN_GAMMATEXTURE = this._texture.gammaSpace;
  124. }
  125. else {
  126. defines.SHEEN_TEXTURE = false;
  127. }
  128. if (this._textureRoughness && MaterialFlags.SheenTextureEnabled) {
  129. PrepareDefinesForMergedUV(this._textureRoughness, defines, "SHEEN_TEXTURE_ROUGHNESS");
  130. }
  131. else {
  132. defines.SHEEN_TEXTURE_ROUGHNESS = false;
  133. }
  134. }
  135. }
  136. }
  137. else {
  138. defines.SHEEN = false;
  139. defines.SHEEN_TEXTURE = false;
  140. defines.SHEEN_TEXTURE_ROUGHNESS = false;
  141. defines.SHEEN_LINKWITHALBEDO = false;
  142. defines.SHEEN_ROUGHNESS = false;
  143. defines.SHEEN_ALBEDOSCALING = false;
  144. defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE = false;
  145. defines.SHEEN_GAMMATEXTURE = false;
  146. defines.SHEEN_TEXTUREDIRECTUV = 0;
  147. defines.SHEEN_TEXTURE_ROUGHNESSDIRECTUV = 0;
  148. }
  149. }
  150. bindForSubMesh(uniformBuffer, scene, engine, subMesh) {
  151. if (!this._isEnabled) {
  152. return;
  153. }
  154. const defines = subMesh.materialDefines;
  155. const isFrozen = this._material.isFrozen;
  156. if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
  157. if ((this._texture || this._textureRoughness) && MaterialFlags.SheenTextureEnabled) {
  158. uniformBuffer.updateFloat4("vSheenInfos", this._texture?.coordinatesIndex ?? 0, this._texture?.level ?? 0, this._textureRoughness?.coordinatesIndex ?? 0, this._textureRoughness?.level ?? 0);
  159. if (this._texture) {
  160. BindTextureMatrix(this._texture, uniformBuffer, "sheen");
  161. }
  162. if (this._textureRoughness && !defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE) {
  163. BindTextureMatrix(this._textureRoughness, uniformBuffer, "sheenRoughness");
  164. }
  165. }
  166. // Sheen
  167. uniformBuffer.updateFloat4("vSheenColor", this.color.r, this.color.g, this.color.b, this.intensity);
  168. if (this._roughness !== null) {
  169. uniformBuffer.updateFloat("vSheenRoughness", this._roughness);
  170. }
  171. }
  172. // Textures
  173. if (scene.texturesEnabled) {
  174. if (this._texture && MaterialFlags.SheenTextureEnabled) {
  175. uniformBuffer.setTexture("sheenSampler", this._texture);
  176. }
  177. if (this._textureRoughness && !defines.SHEEN_USE_ROUGHNESS_FROM_MAINTEXTURE && MaterialFlags.SheenTextureEnabled) {
  178. uniformBuffer.setTexture("sheenRoughnessSampler", this._textureRoughness);
  179. }
  180. }
  181. }
  182. hasTexture(texture) {
  183. if (this._texture === texture) {
  184. return true;
  185. }
  186. if (this._textureRoughness === texture) {
  187. return true;
  188. }
  189. return false;
  190. }
  191. getActiveTextures(activeTextures) {
  192. if (this._texture) {
  193. activeTextures.push(this._texture);
  194. }
  195. if (this._textureRoughness) {
  196. activeTextures.push(this._textureRoughness);
  197. }
  198. }
  199. getAnimatables(animatables) {
  200. if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
  201. animatables.push(this._texture);
  202. }
  203. if (this._textureRoughness && this._textureRoughness.animations && this._textureRoughness.animations.length > 0) {
  204. animatables.push(this._textureRoughness);
  205. }
  206. }
  207. dispose(forceDisposeTextures) {
  208. if (forceDisposeTextures) {
  209. this._texture?.dispose();
  210. this._textureRoughness?.dispose();
  211. }
  212. }
  213. getClassName() {
  214. return "PBRSheenConfiguration";
  215. }
  216. addFallbacks(defines, fallbacks, currentRank) {
  217. if (defines.SHEEN) {
  218. fallbacks.addFallback(currentRank++, "SHEEN");
  219. }
  220. return currentRank;
  221. }
  222. getSamplers(samplers) {
  223. samplers.push("sheenSampler", "sheenRoughnessSampler");
  224. }
  225. getUniforms() {
  226. return {
  227. ubo: [
  228. { name: "vSheenColor", size: 4, type: "vec4" },
  229. { name: "vSheenRoughness", size: 1, type: "float" },
  230. { name: "vSheenInfos", size: 4, type: "vec4" },
  231. { name: "sheenMatrix", size: 16, type: "mat4" },
  232. { name: "sheenRoughnessMatrix", size: 16, type: "mat4" },
  233. ],
  234. };
  235. }
  236. }
  237. __decorate([
  238. serialize(),
  239. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  240. ], PBRSheenConfiguration.prototype, "isEnabled", void 0);
  241. __decorate([
  242. serialize(),
  243. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  244. ], PBRSheenConfiguration.prototype, "linkSheenWithAlbedo", void 0);
  245. __decorate([
  246. serialize()
  247. ], PBRSheenConfiguration.prototype, "intensity", void 0);
  248. __decorate([
  249. serializeAsColor3()
  250. ], PBRSheenConfiguration.prototype, "color", void 0);
  251. __decorate([
  252. serializeAsTexture(),
  253. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  254. ], PBRSheenConfiguration.prototype, "texture", void 0);
  255. __decorate([
  256. serialize(),
  257. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  258. ], PBRSheenConfiguration.prototype, "useRoughnessFromMainTexture", void 0);
  259. __decorate([
  260. serialize(),
  261. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  262. ], PBRSheenConfiguration.prototype, "roughness", void 0);
  263. __decorate([
  264. serializeAsTexture(),
  265. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  266. ], PBRSheenConfiguration.prototype, "textureRoughness", void 0);
  267. __decorate([
  268. serialize(),
  269. expandToProperty("_markAllSubMeshesAsTexturesDirty")
  270. ], PBRSheenConfiguration.prototype, "albedoScaling", void 0);
  271. //# sourceMappingURL=pbrSheenConfiguration.js.map