babylon.shadowGenerator.js 5.0 KB

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