babylon.shadowGenerator.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. // Darkness
  14. this._darkness = 0.;
  15. // Custom render function
  16. var that = this;
  17. var renderSubMesh = function (subMesh) {
  18. var mesh = subMesh.getMesh();
  19. var world = mesh.getWorldMatrix();
  20. var engine = that._scene.getEngine();
  21. if (that.isReady(mesh)) {
  22. engine.enableEffect(that._effect);
  23. // Bones
  24. if (mesh.skeleton && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
  25. that._effect.setMatrix("world", world);
  26. that._effect.setMatrix("viewProjection", that.getTransformMatrix());
  27. that._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
  28. } else {
  29. world.multiplyToRef(that.getTransformMatrix(), that._worldViewProjection);
  30. that._effect.setMatrix("worldViewProjection", that._worldViewProjection);
  31. }
  32. // Bind and draw
  33. mesh.bindAndDraw(subMesh, that._effect, false);
  34. }
  35. };
  36. this._shadowMap.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes) {
  37. var index;
  38. for (index = 0; index < opaqueSubMeshes.length; index++) {
  39. renderSubMesh(opaqueSubMeshes.data[index]);
  40. }
  41. for (index = 0; index < alphaTestSubMeshes.length; index++) {
  42. renderSubMesh(alphaTestSubMeshes.data[index]);
  43. }
  44. };
  45. // Internals
  46. this._viewMatrix = BABYLON.Matrix.Zero();
  47. this._projectionMatrix = BABYLON.Matrix.Zero();
  48. this._transformMatrix = BABYLON.Matrix.Zero();
  49. this._worldViewProjection = BABYLON.Matrix.Zero();
  50. };
  51. // Members
  52. BABYLON.ShadowGenerator.prototype.useVarianceShadowMap = true;
  53. // Properties
  54. BABYLON.ShadowGenerator.prototype.isReady = function (mesh) {
  55. var defines = [];
  56. if (this.useVarianceShadowMap) {
  57. defines.push("#define VSM");
  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. var lightPosition = this._light.position;
  86. var lightDirection = this._light.direction;
  87. if (this._light._computeTransformedPosition()) {
  88. lightPosition = this._light._transformedPosition;
  89. }
  90. if (!this._cachedPosition || !this._cachedDirection || !lightPosition.equals(this._cachedPosition) || !lightDirection.equals(this._cachedDirection)) {
  91. this._cachedPosition = lightPosition.clone();
  92. this._cachedDirection = lightDirection.clone();
  93. var activeCamera = this._scene.activeCamera;
  94. BABYLON.Matrix.LookAtLHToRef(lightPosition, this._light.position.add(lightDirection), BABYLON.Vector3.Up(), this._viewMatrix);
  95. BABYLON.Matrix.PerspectiveFovLHToRef(Math.PI / 2.0, 1.0, activeCamera.minZ, activeCamera.maxZ, this._projectionMatrix);
  96. this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
  97. }
  98. return this._transformMatrix;
  99. };
  100. BABYLON.ShadowGenerator.prototype.getDarkness = function () {
  101. return this._darkness;
  102. };
  103. BABYLON.ShadowGenerator.prototype.setDarkness = function (darkness) {
  104. if (darkness >= 1.0)
  105. this._darkness = 1.0;
  106. else if (darkness <= 0.0)
  107. this._darkness = 0.0;
  108. else
  109. this._darkness = darkness;
  110. };
  111. BABYLON.ShadowGenerator.prototype.dispose = function() {
  112. this._shadowMap.dispose();
  113. };
  114. })();