babylon.furMaterial.ts 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON {
  3. var maxSimultaneousLights = 4;
  4. class FurMaterialDefines extends MaterialDefines {
  5. public DIFFUSE = false;
  6. public HEIGHTMAP = false;
  7. public CLIPPLANE = false;
  8. public ALPHATEST = false;
  9. public POINTSIZE = false;
  10. public FOG = false;
  11. public LIGHT0 = false;
  12. public LIGHT1 = false;
  13. public LIGHT2 = false;
  14. public LIGHT3 = false;
  15. public SPOTLIGHT0 = false;
  16. public SPOTLIGHT1 = false;
  17. public SPOTLIGHT2 = false;
  18. public SPOTLIGHT3 = false;
  19. public HEMILIGHT0 = false;
  20. public HEMILIGHT1 = false;
  21. public HEMILIGHT2 = false;
  22. public HEMILIGHT3 = false;
  23. public DIRLIGHT0 = false;
  24. public DIRLIGHT1 = false;
  25. public DIRLIGHT2 = false;
  26. public DIRLIGHT3 = false;
  27. public POINTLIGHT0 = false;
  28. public POINTLIGHT1 = false;
  29. public POINTLIGHT2 = false;
  30. public POINTLIGHT3 = false;
  31. public SHADOW0 = false;
  32. public SHADOW1 = false;
  33. public SHADOW2 = false;
  34. public SHADOW3 = false;
  35. public SHADOWS = false;
  36. public SHADOWVSM0 = false;
  37. public SHADOWVSM1 = false;
  38. public SHADOWVSM2 = false;
  39. public SHADOWVSM3 = false;
  40. public SHADOWPCF0 = false;
  41. public SHADOWPCF1 = false;
  42. public SHADOWPCF2 = false;
  43. public SHADOWPCF3 = false;
  44. public NORMAL = false;
  45. public UV1 = false;
  46. public UV2 = false;
  47. public VERTEXCOLOR = false;
  48. public VERTEXALPHA = false;
  49. public BONES = false;
  50. public BONES4 = false;
  51. public BonesPerMesh = 0;
  52. public INSTANCES = false;
  53. public HIGHLEVEL = false;
  54. constructor() {
  55. super();
  56. this._keys = Object.keys(this);
  57. }
  58. }
  59. export class FurMaterial extends Material {
  60. public diffuseTexture: BaseTexture;
  61. public heightTexture: BaseTexture;
  62. public diffuseColor = new Color3(1, 1, 1);
  63. public furLength: number = 1;
  64. public furAngle: number = 0;
  65. public furColor = new Color3(0.44,0.21,0.02);
  66. public furOffset: number = 0.0;
  67. public furSpacing: number = 12;
  68. public furGravity = new Vector3(0, 0, 0);
  69. public furSpeed: number = 100;
  70. public furDensity: number = 20;
  71. public furTexture: DynamicTexture;
  72. public disableLighting = false;
  73. public highLevelFur: boolean = true;
  74. private _worldViewProjectionMatrix = Matrix.Zero();
  75. private _scaledDiffuse = new Color3(1.,1.,1.);
  76. private _renderId: number;
  77. private _furTime: number = 0;
  78. private _defines = new FurMaterialDefines();
  79. private _cachedDefines = new FurMaterialDefines();
  80. constructor(name: string, scene: Scene) {
  81. super(name, scene);
  82. this._cachedDefines.BonesPerMesh = -1;
  83. }
  84. public get furTime() {
  85. return this._furTime;
  86. }
  87. public set furTime(furTime: number) {
  88. this._furTime = furTime;
  89. }
  90. public needAlphaBlending(): boolean {
  91. return (this.alpha < 1.0);
  92. }
  93. public needAlphaTesting(): boolean {
  94. return false;
  95. }
  96. public getAlphaTestTexture(): BaseTexture {
  97. return null;
  98. }
  99. // Methods
  100. private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
  101. if (!mesh) {
  102. return true;
  103. }
  104. if (this._defines.INSTANCES !== useInstances) {
  105. return false;
  106. }
  107. if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
  108. return true;
  109. }
  110. return false;
  111. }
  112. public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
  113. if (this.checkReadyOnlyOnce) {
  114. if (this._wasPreviouslyReady) {
  115. return true;
  116. }
  117. }
  118. var scene = this.getScene();
  119. if (!this.checkReadyOnEveryCall) {
  120. if (this._renderId === scene.getRenderId()) {
  121. if (this._checkCache(scene, mesh, useInstances)) {
  122. return true;
  123. }
  124. }
  125. }
  126. var engine = scene.getEngine();
  127. var needNormals = false;
  128. var needUVs = false;
  129. this._defines.reset();
  130. // Textures
  131. if (scene.texturesEnabled) {
  132. if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
  133. if (!this.diffuseTexture.isReady()) {
  134. return false;
  135. } else {
  136. needUVs = true;
  137. this._defines.DIFFUSE = true;
  138. }
  139. }
  140. if (this.heightTexture) {
  141. if (!this.heightTexture.isReady()) {
  142. return false;
  143. } else {
  144. needUVs = true;
  145. this._defines.HEIGHTMAP = true;
  146. }
  147. }
  148. }
  149. // Effect
  150. if (scene.clipPlane) {
  151. this._defines.CLIPPLANE = true;
  152. }
  153. if (engine.getAlphaTesting()) {
  154. this._defines.ALPHATEST = true;
  155. }
  156. // Point size
  157. if (this.pointsCloud || scene.forcePointsCloud) {
  158. this._defines.POINTSIZE = true;
  159. }
  160. // Fog
  161. if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
  162. this._defines.FOG = true;
  163. }
  164. // High level
  165. if (this.highLevelFur) {
  166. this._defines.HIGHLEVEL = true;
  167. }
  168. var lightIndex = 0;
  169. if (scene.lightsEnabled && !this.disableLighting) {
  170. for (var index = 0; index < scene.lights.length; index++) {
  171. var light = scene.lights[index];
  172. if (!light.isEnabled()) {
  173. continue;
  174. }
  175. // Excluded check
  176. if (light._excludedMeshesIds.length > 0) {
  177. for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
  178. var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
  179. if (excludedMesh) {
  180. light.excludedMeshes.push(excludedMesh);
  181. }
  182. }
  183. light._excludedMeshesIds = [];
  184. }
  185. // Included check
  186. if (light._includedOnlyMeshesIds.length > 0) {
  187. for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
  188. var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
  189. if (includedOnlyMesh) {
  190. light.includedOnlyMeshes.push(includedOnlyMesh);
  191. }
  192. }
  193. light._includedOnlyMeshesIds = [];
  194. }
  195. if (!light.canAffectMesh(mesh)) {
  196. continue;
  197. }
  198. needNormals = true;
  199. this._defines["LIGHT" + lightIndex] = true;
  200. var type;
  201. if (light instanceof SpotLight) {
  202. type = "SPOTLIGHT" + lightIndex;
  203. } else if (light instanceof HemisphericLight) {
  204. type = "HEMILIGHT" + lightIndex;
  205. } else if (light instanceof PointLight) {
  206. type = "POINTLIGHT" + lightIndex;
  207. } else {
  208. type = "DIRLIGHT" + lightIndex;
  209. }
  210. this._defines[type] = true;
  211. // Shadows
  212. if (scene.shadowsEnabled) {
  213. var shadowGenerator = light.getShadowGenerator();
  214. if (mesh && mesh.receiveShadows && shadowGenerator) {
  215. this._defines["SHADOW" + lightIndex] = true;
  216. this._defines.SHADOWS = true;
  217. if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
  218. this._defines["SHADOWVSM" + lightIndex] = true;
  219. }
  220. if (shadowGenerator.usePoissonSampling) {
  221. this._defines["SHADOWPCF" + lightIndex] = true;
  222. }
  223. }
  224. }
  225. lightIndex++;
  226. if (lightIndex === maxSimultaneousLights)
  227. break;
  228. }
  229. }
  230. // Attribs
  231. if (mesh) {
  232. if (needNormals && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
  233. this._defines.NORMAL = true;
  234. }
  235. if (needUVs) {
  236. if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
  237. this._defines.UV1 = true;
  238. }
  239. if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
  240. this._defines.UV2 = true;
  241. }
  242. }
  243. if (mesh.useVertexColors && mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {
  244. this._defines.VERTEXCOLOR = true;
  245. if (mesh.hasVertexAlpha) {
  246. this._defines.VERTEXALPHA = true;
  247. }
  248. }
  249. if (mesh.useBones && mesh.computeBonesUsingShaders) {
  250. this._defines.BONES = true;
  251. this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
  252. this._defines.BONES4 = true;
  253. }
  254. // Instances
  255. if (useInstances) {
  256. this._defines.INSTANCES = true;
  257. }
  258. }
  259. // Get correct effect
  260. if (!this._defines.isEqual(this._cachedDefines)) {
  261. this._defines.cloneTo(this._cachedDefines);
  262. scene.resetCachedMaterial();
  263. // Fallbacks
  264. var fallbacks = new EffectFallbacks();
  265. if (this._defines.FOG) {
  266. fallbacks.addFallback(1, "FOG");
  267. }
  268. for (lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
  269. if (!this._defines["LIGHT" + lightIndex]) {
  270. continue;
  271. }
  272. if (lightIndex > 0) {
  273. fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
  274. }
  275. if (this._defines["SHADOW" + lightIndex]) {
  276. fallbacks.addFallback(0, "SHADOW" + lightIndex);
  277. }
  278. if (this._defines["SHADOWPCF" + lightIndex]) {
  279. fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
  280. }
  281. if (this._defines["SHADOWVSM" + lightIndex]) {
  282. fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
  283. }
  284. }
  285. if (this._defines.BONES4) {
  286. fallbacks.addFallback(0, "BONES4");
  287. }
  288. //Attributes
  289. var attribs = [VertexBuffer.PositionKind];
  290. if (this._defines.NORMAL) {
  291. attribs.push(VertexBuffer.NormalKind);
  292. }
  293. if (this._defines.UV1) {
  294. attribs.push(VertexBuffer.UVKind);
  295. }
  296. if (this._defines.UV2) {
  297. attribs.push(VertexBuffer.UV2Kind);
  298. }
  299. if (this._defines.VERTEXCOLOR) {
  300. attribs.push(VertexBuffer.ColorKind);
  301. }
  302. if (this._defines.BONES) {
  303. attribs.push(VertexBuffer.MatricesIndicesKind);
  304. attribs.push(VertexBuffer.MatricesWeightsKind);
  305. }
  306. if (this._defines.INSTANCES) {
  307. attribs.push("world0");
  308. attribs.push("world1");
  309. attribs.push("world2");
  310. attribs.push("world3");
  311. }
  312. // Legacy browser patch
  313. var shaderName = "fur";
  314. var join = this._defines.toString();
  315. this._effect = scene.getEngine().createEffect(shaderName,
  316. attribs,
  317. ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
  318. "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
  319. "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
  320. "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
  321. "vLightData3", "vLightDiffuse3", "vLightSpecular3", "vLightDirection3", "vLightGround3", "lightMatrix3",
  322. "vFogInfos", "vFogColor", "pointSize",
  323. "vDiffuseInfos",
  324. "mBones",
  325. "vClipPlane", "diffuseMatrix",
  326. "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
  327. "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing", "furDensity"
  328. ],
  329. ["diffuseSampler",
  330. "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3",
  331. "heightTexture", "furTexture"
  332. ],
  333. join, fallbacks, this.onCompiled, this.onError);
  334. }
  335. if (!this._effect.isReady()) {
  336. return false;
  337. }
  338. this._renderId = scene.getRenderId();
  339. this._wasPreviouslyReady = true;
  340. if (mesh) {
  341. if (!mesh._materialDefines) {
  342. mesh._materialDefines = new FurMaterialDefines();
  343. }
  344. this._defines.cloneTo(mesh._materialDefines);
  345. }
  346. return true;
  347. }
  348. public bindOnlyWorldMatrix(world: Matrix): void {
  349. this._effect.setMatrix("world", world);
  350. }
  351. public bind(world: Matrix, mesh?: Mesh): void {
  352. var scene = this.getScene();
  353. // Matrices
  354. this.bindOnlyWorldMatrix(world);
  355. this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
  356. // Bones
  357. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  358. this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
  359. }
  360. if (scene.getCachedMaterial() !== this) {
  361. // Textures
  362. if (this.diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
  363. this._effect.setTexture("diffuseSampler", this.diffuseTexture);
  364. this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
  365. this._effect.setMatrix("diffuseMatrix", this.diffuseTexture.getTextureMatrix());
  366. }
  367. if (this.heightTexture) {
  368. this._effect.setTexture("heightTexture", this.heightTexture);
  369. }
  370. // Clip plane
  371. if (scene.clipPlane) {
  372. var clipPlane = scene.clipPlane;
  373. this._effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
  374. }
  375. // Point size
  376. if (this.pointsCloud) {
  377. this._effect.setFloat("pointSize", this.pointSize);
  378. }
  379. this._effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.position);
  380. }
  381. this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
  382. if (scene.lightsEnabled && !this.disableLighting) {
  383. var lightIndex = 0;
  384. for (var index = 0; index < scene.lights.length; index++) {
  385. var light = scene.lights[index];
  386. if (!light.isEnabled()) {
  387. continue;
  388. }
  389. if (!light.canAffectMesh(mesh)) {
  390. continue;
  391. }
  392. if (light instanceof PointLight) {
  393. // Point Light
  394. light.transferToEffect(this._effect, "vLightData" + lightIndex);
  395. } else if (light instanceof DirectionalLight) {
  396. // Directional Light
  397. light.transferToEffect(this._effect, "vLightData" + lightIndex);
  398. } else if (light instanceof SpotLight) {
  399. // Spot Light
  400. light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
  401. } else if (light instanceof HemisphericLight) {
  402. // Hemispheric Light
  403. light.transferToEffect(this._effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
  404. }
  405. light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
  406. this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
  407. // Shadows
  408. if (scene.shadowsEnabled) {
  409. var shadowGenerator = light.getShadowGenerator();
  410. if (mesh.receiveShadows && shadowGenerator) {
  411. this._effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
  412. this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
  413. this._effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
  414. }
  415. }
  416. lightIndex++;
  417. if (lightIndex === maxSimultaneousLights)
  418. break;
  419. }
  420. }
  421. // View
  422. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
  423. this._effect.setMatrix("view", scene.getViewMatrix());
  424. }
  425. // Fog
  426. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
  427. this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
  428. this._effect.setColor3("vFogColor", scene.fogColor);
  429. }
  430. this._effect.setFloat("furLength", this.furLength);
  431. this._effect.setFloat("furAngle", this.furAngle);
  432. this._effect.setColor4("furColor", this.furColor, 1.0);
  433. if (this.highLevelFur) {
  434. this._effect.setVector3("furGravity", this.furGravity);
  435. this._effect.setFloat("furOffset", this.furOffset);
  436. this._effect.setFloat("furSpacing", this.furSpacing);
  437. this._effect.setFloat("furDensity", this.furDensity);
  438. this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
  439. this._effect.setFloat("furTime", this._furTime);
  440. this._effect.setTexture("furTexture", this.furTexture);
  441. }
  442. super.bind(world, mesh);
  443. }
  444. public getAnimatables(): IAnimatable[] {
  445. var results = [];
  446. if (this.diffuseTexture && this.diffuseTexture.animations && this.diffuseTexture.animations.length > 0) {
  447. results.push(this.diffuseTexture);
  448. }
  449. if (this.heightTexture && this.heightTexture.animations && this.heightTexture.animations.length > 0) {
  450. results.push(this.heightTexture);
  451. }
  452. return results;
  453. }
  454. public dispose(forceDisposeEffect?: boolean): void {
  455. if (this.diffuseTexture) {
  456. this.diffuseTexture.dispose();
  457. }
  458. super.dispose(forceDisposeEffect);
  459. }
  460. public clone(name: string): FurMaterial {
  461. var newMaterial = new FurMaterial(name, this.getScene());
  462. // Base material
  463. this.copyTo(newMaterial);
  464. // Fur material
  465. if (this.diffuseTexture && this.diffuseTexture.clone) {
  466. newMaterial.diffuseTexture = this.diffuseTexture.clone();
  467. }
  468. if (this.heightTexture && this.heightTexture.clone) {
  469. newMaterial.heightTexture = this.heightTexture.clone();
  470. }
  471. if (this.diffuseColor && this.diffuseColor.clone) {
  472. newMaterial.diffuseColor = this.diffuseColor.clone();
  473. }
  474. return newMaterial;
  475. }
  476. public serialize(): any {
  477. var serializationObject = super.serialize();
  478. serializationObject.customType = "BABYLON.FurMaterial";
  479. serializationObject.diffuseColor = this.diffuseColor.asArray();
  480. serializationObject.disableLighting = this.disableLighting;
  481. serializationObject.furLength = this.furLength;
  482. serializationObject.furAngle = this.furAngle;
  483. serializationObject.furColor = this.furColor.asArray();
  484. serializationObject.furGravity = this.furGravity.asArray();
  485. serializationObject.furSpacing = this.furSpacing;
  486. serializationObject.furSpeed = this.furSpeed;
  487. serializationObject.furDensity = this.furDensity;
  488. if (this.diffuseTexture) {
  489. serializationObject.diffuseTexture = this.diffuseTexture.serialize();
  490. }
  491. if (this.heightTexture) {
  492. serializationObject.heightTexture = this.heightTexture.serialize();
  493. }
  494. return serializationObject;
  495. }
  496. public static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial {
  497. var material = new FurMaterial(source.name, scene);
  498. material.diffuseColor = Color3.FromArray(source.diffuseColor);
  499. material.furLength = source.furLength;
  500. material.furAngle = source.furAngle;
  501. material.furColor = Color3.FromArray(source.furColor);
  502. material.furGravity = Vector3.FromArray(source.furGravity);
  503. material.furSpacing = source.furSpacing;
  504. material.furSpeed = source.furSpeed;
  505. material.furDensity = source.furDensity;
  506. material.disableLighting = source.disableLighting;
  507. material.alpha = source.alpha;
  508. material.id = source.id;
  509. Tags.AddTagsTo(material, source.tags);
  510. material.backFaceCulling = source.backFaceCulling;
  511. material.wireframe = source.wireframe;
  512. if (source.diffuseTexture) {
  513. material.diffuseTexture = Texture.Parse(source.diffuseTexture, scene, rootUrl);
  514. }
  515. if (source.heightTexture) {
  516. material.heightTexture = Texture.Parse(source.heightTexture, scene, rootUrl);
  517. }
  518. if (source.checkReadyOnlyOnce) {
  519. material.checkReadyOnlyOnce = source.checkReadyOnlyOnce;
  520. }
  521. return material;
  522. }
  523. public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
  524. // Generate fur textures
  525. var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
  526. var context = texture.getContext();
  527. for ( var i = 0; i < 20000; ++i ) {
  528. context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
  529. context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
  530. }
  531. texture.update(false);
  532. texture.wrapU = Texture.WRAP_ADDRESSMODE;
  533. texture.wrapV = Texture.WRAP_ADDRESSMODE;
  534. return texture;
  535. }
  536. // Creates and returns an array of meshes used as shells for the Fur Material
  537. // that can be disposed later in your code
  538. // The quality is in interval [0, 100]
  539. public static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[] {
  540. var meshes = [sourceMesh];
  541. var mat: FurMaterial = <FurMaterial>sourceMesh.material;
  542. if (!(mat instanceof FurMaterial)) {
  543. throw "The material of the source mesh must be a Fur Material";
  544. }
  545. for (var i = 1; i < quality; i++) {
  546. var offsetFur = new BABYLON.FurMaterial(mat.name + i, sourceMesh.getScene());
  547. offsetFur.furLength = mat.furLength;
  548. offsetFur.furAngle = mat.furAngle;
  549. offsetFur.furGravity = mat.furGravity;
  550. offsetFur.furSpacing = mat.furSpacing;
  551. offsetFur.furSpeed = mat.furSpeed;
  552. offsetFur.furColor = mat.furColor;
  553. offsetFur.diffuseTexture = mat.diffuseTexture;
  554. offsetFur.furOffset = i / quality;
  555. offsetFur.furTexture = mat.furTexture;
  556. offsetFur.highLevelFur = mat.highLevelFur;
  557. offsetFur.furTime = mat.furTime;
  558. offsetFur.furDensity = mat.furDensity;
  559. var offsetMesh = sourceMesh.clone(sourceMesh.name + i);
  560. offsetMesh.material = offsetFur;
  561. offsetMesh.skeleton = sourceMesh.skeleton;
  562. offsetMesh.parent = sourceMesh;
  563. meshes.push(offsetMesh);
  564. }
  565. return meshes;
  566. }
  567. }
  568. }