babylon.shadowGenerator.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. var BABYLON = BABYLON || {};
  2. (function () {
  3. BABYLON.ShadowGenerator = function (mapSize, light) {
  4. this._light = light;
  5. this._scene = light.getScene();
  6. light._shadowGenerator = this;
  7. // Render target
  8. this._shadowMap = new BABYLON.RenderTargetTexture(light.name + "_shadowMap", mapSize, this._scene, false);
  9. this._shadowMap.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
  10. this._shadowMap.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
  11. this._shadowMap.renderParticles = false;
  12. // Custom render function
  13. var that = this;
  14. var renderSubMesh = function (subMesh) {
  15. var mesh = subMesh.getMesh();
  16. var world = mesh.getWorldMatrix();
  17. var engine = that._scene.getEngine();
  18. if (that.isReady(mesh)) {
  19. engine.enableEffect(that._effect);
  20. // Bones
  21. if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
  22. that._effect.setMatrix("world", world);
  23. that._effect.setMatrix("viewProjection", that.getTransformMatrix());
  24. that._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
  25. } else {
  26. world.multiplyToRef(that.getTransformMatrix(), that._worldViewProjection);
  27. that._effect.setMatrix("worldViewProjection", that._worldViewProjection);
  28. }
  29. // Bind and draw
  30. mesh.bindAndDraw(subMesh, that._effect, false);
  31. }
  32. };
  33. this._shadowMap.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes) {
  34. var index;
  35. for (index = 0; index < opaqueSubMeshes.length; index++) {
  36. renderSubMesh(opaqueSubMeshes.data[index]);
  37. }
  38. for (index = 0; index < alphaTestSubMeshes.length; index++) {
  39. renderSubMesh(alphaTestSubMeshes.data[index]);
  40. }
  41. };
  42. // Internals
  43. this._viewMatrix = BABYLON.Matrix.Zero();
  44. this._projectionMatrix = BABYLON.Matrix.Zero();
  45. this._transformMatrix = BABYLON.Matrix.Zero();
  46. this._worldViewProjection = BABYLON.Matrix.Zero();
  47. };
  48. // Members
  49. BABYLON.ShadowGenerator.prototype.useVarianceShadowMap = true;
  50. // Properties
  51. BABYLON.ShadowGenerator.prototype.isReady = function (mesh) {
  52. var defines = [];
  53. if (this.useVarianceShadowMap) {
  54. defines.push("#define VSM");
  55. }
  56. if (BABYLON.Tools.isIE()) {
  57. defines.push("#define IE");
  58. }
  59. var attribs = [BABYLON.VertexBuffer.PositionKind];
  60. if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
  61. attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
  62. attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
  63. defines.push("#define BONES");
  64. defines.push("#define BonesPerMesh " + mesh.skeleton.bones.length);
  65. }
  66. // Get correct effect
  67. var join = defines.join("\n");
  68. if (this._cachedDefines != join) {
  69. this._cachedDefines = join;
  70. this._effect = this._scene.getEngine().createEffect("shadowMap",
  71. attribs,
  72. ["world", "mBones", "viewProjection", "worldViewProjection"],
  73. [], join);
  74. }
  75. return this._effect.isReady();
  76. };
  77. BABYLON.ShadowGenerator.prototype.getShadowMap = function () {
  78. return this._shadowMap;
  79. };
  80. BABYLON.ShadowGenerator.prototype.getLight = function () {
  81. return this._light;
  82. };
  83. // Methods
  84. BABYLON.ShadowGenerator.prototype.getTransformMatrix = function () {
  85. if (!this._cachedPosition || !this._cachedDirection || !this._light.position.equals(this._cachedPosition) || !this._light.direction.equals(this._cachedDirection)) {
  86. this._cachedPosition = this._light.position.clone();
  87. this._cachedDirection = this._light.direction.clone();
  88. var activeCamera = this._scene.activeCamera;
  89. BABYLON.Matrix.LookAtLHToRef(this._light.position, this._light.position.add(this._light.direction), BABYLON.Vector3.Up(), this._viewMatrix);
  90. BABYLON.Matrix.PerspectiveFovLHToRef(Math.PI / 2.0, 1.0, activeCamera.minZ, activeCamera.maxZ, this._projectionMatrix);
  91. this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
  92. }
  93. return this._transformMatrix;
  94. };
  95. BABYLON.ShadowGenerator.prototype.dispose = function() {
  96. this._shadowMap.dispose();
  97. };
  98. })();