babylon.pbrMaterial.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var maxSimultaneousLights = 4;
  9. var PBRMaterialDefines = (function () {
  10. function PBRMaterialDefines() {
  11. this.ALBEDO = false;
  12. this.CLIPPLANE = false;
  13. this.ALPHATEST = false;
  14. this.FOG = false;
  15. this.NORMAL = false;
  16. this.UV1 = false;
  17. this.UV2 = false;
  18. this.VERTEXCOLOR = false;
  19. this.VERTEXALPHA = false;
  20. this.BONES = false;
  21. this.BONES4 = false;
  22. this.BonesPerMesh = 0;
  23. this.INSTANCES = false;
  24. this.POINTSIZE = false;
  25. this._keys = Object.keys(this);
  26. }
  27. PBRMaterialDefines.prototype.isEqual = function (other) {
  28. for (var index = 0; index < this._keys.length; index++) {
  29. var prop = this._keys[index];
  30. if (this[prop] !== other[prop]) {
  31. return false;
  32. }
  33. }
  34. return true;
  35. };
  36. PBRMaterialDefines.prototype.cloneTo = function (other) {
  37. for (var index = 0; index < this._keys.length; index++) {
  38. var prop = this._keys[index];
  39. other[prop] = this[prop];
  40. }
  41. };
  42. PBRMaterialDefines.prototype.reset = function () {
  43. for (var index = 0; index < this._keys.length; index++) {
  44. var prop = this._keys[index];
  45. if (prop === "BonesPerMesh") {
  46. this[prop] = 0;
  47. continue;
  48. }
  49. this[prop] = false;
  50. }
  51. };
  52. PBRMaterialDefines.prototype.toString = function () {
  53. var result = "";
  54. for (var index = 0; index < this._keys.length; index++) {
  55. var prop = this._keys[index];
  56. if (prop === "BonesPerMesh" && this[prop] > 0) {
  57. result += "#define BonesPerMesh " + this[prop] + "\n";
  58. continue;
  59. }
  60. if (this[prop]) {
  61. result += "#define " + prop + "\n";
  62. }
  63. }
  64. return result;
  65. };
  66. return PBRMaterialDefines;
  67. })();
  68. var PBRMaterial = (function (_super) {
  69. __extends(PBRMaterial, _super);
  70. function PBRMaterial(name, scene) {
  71. _super.call(this, name, scene);
  72. this.albedoColor = new BABYLON.Color3(1, 1, 1);
  73. this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
  74. this._globalAmbientColor = new BABYLON.Color3(0, 0, 0);
  75. this._scaledDiffuse = new BABYLON.Color3();
  76. this._scaledSpecular = new BABYLON.Color3();
  77. this._defines = new PBRMaterialDefines();
  78. this._cachedDefines = new PBRMaterialDefines();
  79. this._cachedDefines.BonesPerMesh = -1;
  80. }
  81. PBRMaterial.prototype.needAlphaBlending = function () {
  82. return this.alpha < 1.0;
  83. };
  84. PBRMaterial.prototype.needAlphaTesting = function () {
  85. return false;
  86. };
  87. PBRMaterial.prototype.getAlphaTestTexture = function () {
  88. return null;
  89. };
  90. // Methods
  91. PBRMaterial.prototype.isReady = function (mesh, useInstances) {
  92. if (this.checkReadyOnlyOnce) {
  93. if (this._wasPreviouslyReady) {
  94. return true;
  95. }
  96. }
  97. var scene = this.getScene();
  98. if (!this.checkReadyOnEveryCall) {
  99. if (this._renderId === scene.getRenderId()) {
  100. return true;
  101. }
  102. }
  103. var engine = scene.getEngine();
  104. var needNormals = false;
  105. var needUVs = false;
  106. this._defines.reset();
  107. // Textures
  108. if (scene.texturesEnabled) {
  109. }
  110. // Effect
  111. if (scene.clipPlane) {
  112. this._defines.CLIPPLANE = true;
  113. }
  114. if (engine.getAlphaTesting()) {
  115. this._defines.ALPHATEST = true;
  116. }
  117. // Point size
  118. if (this.pointsCloud || scene.forcePointsCloud) {
  119. this._defines.POINTSIZE = true;
  120. }
  121. // Fog
  122. if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled) {
  123. this._defines.FOG = true;
  124. }
  125. // Lights
  126. // Attribs
  127. if (mesh) {
  128. if (needNormals && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  129. this._defines.NORMAL = true;
  130. }
  131. if (needUVs) {
  132. if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
  133. this._defines.UV1 = true;
  134. }
  135. if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
  136. this._defines.UV2 = true;
  137. }
  138. }
  139. if (mesh.useVertexColors && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
  140. this._defines.VERTEXCOLOR = true;
  141. if (mesh.hasVertexAlpha) {
  142. this._defines.VERTEXALPHA = true;
  143. }
  144. }
  145. if (mesh.useBones && mesh.computeBonesUsingShaders) {
  146. this._defines.BONES = true;
  147. this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
  148. this._defines.BONES4 = true;
  149. }
  150. // Instances
  151. if (useInstances) {
  152. this._defines.INSTANCES = true;
  153. }
  154. }
  155. // Get correct effect
  156. if (!this._defines.isEqual(this._cachedDefines)) {
  157. this._defines.cloneTo(this._cachedDefines);
  158. scene.resetCachedMaterial();
  159. // Fallbacks
  160. var fallbacks = new BABYLON.EffectFallbacks();
  161. if (this._defines.FOG) {
  162. fallbacks.addFallback(1, "FOG");
  163. }
  164. if (this._defines.BONES4) {
  165. fallbacks.addFallback(0, "BONES4");
  166. }
  167. //Attributes
  168. var attribs = [BABYLON.VertexBuffer.PositionKind];
  169. if (this._defines.NORMAL) {
  170. attribs.push(BABYLON.VertexBuffer.NormalKind);
  171. }
  172. if (this._defines.UV1) {
  173. attribs.push(BABYLON.VertexBuffer.UVKind);
  174. }
  175. if (this._defines.UV2) {
  176. attribs.push(BABYLON.VertexBuffer.UV2Kind);
  177. }
  178. if (this._defines.VERTEXCOLOR) {
  179. attribs.push(BABYLON.VertexBuffer.ColorKind);
  180. }
  181. if (this._defines.BONES) {
  182. attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
  183. attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
  184. }
  185. if (this._defines.INSTANCES) {
  186. attribs.push("world0");
  187. attribs.push("world1");
  188. attribs.push("world2");
  189. attribs.push("world3");
  190. }
  191. // Legacy browser patch
  192. var join = this._defines.toString();
  193. this._effect = scene.getEngine().createEffect("pbr", attribs, ["world", "view", "viewProjection", "vEyePosition", "vAlbedoColor",
  194. "vFogInfos", "vFogColor", "pointSize",
  195. "mBones",
  196. "vClipPlane",
  197. ], [], join, fallbacks, this.onCompiled, this.onError);
  198. }
  199. if (!this._effect.isReady()) {
  200. return false;
  201. }
  202. this._renderId = scene.getRenderId();
  203. this._wasPreviouslyReady = true;
  204. return true;
  205. };
  206. PBRMaterial.prototype.bindOnlyWorldMatrix = function (world) {
  207. this._effect.setMatrix("world", world);
  208. };
  209. PBRMaterial.prototype.bind = function (world, mesh) {
  210. var scene = this.getScene();
  211. // Matrices
  212. this.bindOnlyWorldMatrix(world);
  213. this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
  214. // Bones
  215. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  216. this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
  217. }
  218. if (scene.getCachedMaterial() !== this) {
  219. // Clip plane
  220. if (scene.clipPlane) {
  221. var clipPlane = scene.clipPlane;
  222. this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
  223. }
  224. this._effect.setVector3("vEyePosition", scene.activeCamera.position);
  225. }
  226. // Point size
  227. if (this.pointsCloud) {
  228. this._effect.setFloat("pointSize", this.pointSize);
  229. }
  230. // Colors
  231. this._effect.setColor4("vAlbedoColor", this.albedoColor, this.alpha * mesh.visibility);
  232. // View
  233. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
  234. this._effect.setMatrix("view", scene.getViewMatrix());
  235. }
  236. // Fog
  237. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
  238. this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
  239. this._effect.setColor3("vFogColor", scene.fogColor);
  240. }
  241. _super.prototype.bind.call(this, world, mesh);
  242. };
  243. PBRMaterial.prototype.getAnimatables = function () {
  244. var results = [];
  245. return results;
  246. };
  247. PBRMaterial.prototype.dispose = function (forceDisposeEffect) {
  248. _super.prototype.dispose.call(this, forceDisposeEffect);
  249. };
  250. PBRMaterial.prototype.clone = function (name) {
  251. var newPBRMaterial = new PBRMaterial(name, this.getScene());
  252. // Base material
  253. this.copyTo(newPBRMaterial);
  254. // PBRMaterial material
  255. newPBRMaterial.albedoColor = this.albedoColor.clone();
  256. return newPBRMaterial;
  257. };
  258. return PBRMaterial;
  259. })(BABYLON.Material);
  260. BABYLON.PBRMaterial = PBRMaterial;
  261. })(BABYLON || (BABYLON = {}));