babylon.materialHelper.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. var BABYLON;
  2. (function (BABYLON) {
  3. var maxSimultaneousLights = 4;
  4. var MaterialHelper = (function () {
  5. function MaterialHelper() {
  6. }
  7. MaterialHelper.PrepareDefinesForLights = function (scene, mesh, defines) {
  8. var lightIndex = 0;
  9. var needNormals = false;
  10. for (var index = 0; index < scene.lights.length; index++) {
  11. var light = scene.lights[index];
  12. if (!light.isEnabled()) {
  13. continue;
  14. }
  15. // Excluded check
  16. if (light._excludedMeshesIds.length > 0) {
  17. for (var excludedIndex = 0; excludedIndex < light._excludedMeshesIds.length; excludedIndex++) {
  18. var excludedMesh = scene.getMeshByID(light._excludedMeshesIds[excludedIndex]);
  19. if (excludedMesh) {
  20. light.excludedMeshes.push(excludedMesh);
  21. }
  22. }
  23. light._excludedMeshesIds = [];
  24. }
  25. // Included check
  26. if (light._includedOnlyMeshesIds.length > 0) {
  27. for (var includedOnlyIndex = 0; includedOnlyIndex < light._includedOnlyMeshesIds.length; includedOnlyIndex++) {
  28. var includedOnlyMesh = scene.getMeshByID(light._includedOnlyMeshesIds[includedOnlyIndex]);
  29. if (includedOnlyMesh) {
  30. light.includedOnlyMeshes.push(includedOnlyMesh);
  31. }
  32. }
  33. light._includedOnlyMeshesIds = [];
  34. }
  35. if (!light.canAffectMesh(mesh)) {
  36. continue;
  37. }
  38. needNormals = true;
  39. defines["LIGHT" + lightIndex] = true;
  40. var type;
  41. if (light instanceof BABYLON.SpotLight) {
  42. type = "SPOTLIGHT" + lightIndex;
  43. }
  44. else if (light instanceof BABYLON.HemisphericLight) {
  45. type = "HEMILIGHT" + lightIndex;
  46. }
  47. else if (light instanceof BABYLON.PointLight) {
  48. type = "POINTLIGHT" + lightIndex;
  49. }
  50. else {
  51. type = "DIRLIGHT" + lightIndex;
  52. }
  53. defines[type] = true;
  54. // Specular
  55. if (!light.specular.equalsFloats(0, 0, 0) && defines["SPECULARTERM"] !== undefined) {
  56. defines["SPECULARTERM"] = true;
  57. }
  58. // Shadows
  59. if (scene.shadowsEnabled) {
  60. var shadowGenerator = light.getShadowGenerator();
  61. if (mesh && mesh.receiveShadows && shadowGenerator) {
  62. defines["SHADOW" + lightIndex] = true;
  63. defines["SHADOWS"] = true;
  64. if (shadowGenerator.useVarianceShadowMap || shadowGenerator.useBlurVarianceShadowMap) {
  65. defines["SHADOWVSM" + lightIndex] = true;
  66. }
  67. if (shadowGenerator.usePoissonSampling) {
  68. defines["SHADOWPCF" + lightIndex] = true;
  69. }
  70. }
  71. }
  72. lightIndex++;
  73. if (lightIndex === maxSimultaneousLights)
  74. break;
  75. }
  76. return needNormals;
  77. };
  78. MaterialHelper.HandleFallbacksForShadows = function (defines, fallbacks) {
  79. for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
  80. if (!defines["LIGHT" + lightIndex]) {
  81. continue;
  82. }
  83. if (lightIndex > 0) {
  84. fallbacks.addFallback(lightIndex, "LIGHT" + lightIndex);
  85. }
  86. if (defines["SHADOW" + lightIndex]) {
  87. fallbacks.addFallback(0, "SHADOW" + lightIndex);
  88. }
  89. if (defines["SHADOWPCF" + lightIndex]) {
  90. fallbacks.addFallback(0, "SHADOWPCF" + lightIndex);
  91. }
  92. if (defines["SHADOWVSM" + lightIndex]) {
  93. fallbacks.addFallback(0, "SHADOWVSM" + lightIndex);
  94. }
  95. }
  96. };
  97. MaterialHelper.PrepareAttributesForBones = function (attribs, mesh, defines, fallbacks) {
  98. if (defines["NUM_BONE_INFLUENCERS"] > 0) {
  99. fallbacks.addCPUSkinningFallback(0, mesh);
  100. attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
  101. attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
  102. if (defines["NUM_BONE_INFLUENCERS"] > 4) {
  103. attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
  104. attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
  105. }
  106. }
  107. };
  108. MaterialHelper.PrepareAttributesForInstances = function (attribs, defines) {
  109. if (defines["INSTANCES"]) {
  110. attribs.push("world0");
  111. attribs.push("world1");
  112. attribs.push("world2");
  113. attribs.push("world3");
  114. }
  115. };
  116. // Bindings
  117. MaterialHelper.BindLightShadow = function (light, scene, mesh, lightIndex, effect, depthValuesAlreadySet) {
  118. var shadowGenerator = light.getShadowGenerator();
  119. if (mesh.receiveShadows && shadowGenerator) {
  120. if (!light.needCube()) {
  121. effect.setMatrix("lightMatrix" + lightIndex, shadowGenerator.getTransformMatrix());
  122. }
  123. else {
  124. if (!depthValuesAlreadySet) {
  125. depthValuesAlreadySet = true;
  126. effect.setFloat2("depthValues", scene.activeCamera.minZ, scene.activeCamera.maxZ);
  127. }
  128. }
  129. effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMapForRendering());
  130. effect.setFloat3("shadowsInfo" + lightIndex, shadowGenerator.getDarkness(), shadowGenerator.blurScale / shadowGenerator.getShadowMap().getSize().width, shadowGenerator.bias);
  131. }
  132. return depthValuesAlreadySet;
  133. };
  134. MaterialHelper.BindLightProperties = function (light, effect, lightIndex) {
  135. if (light instanceof BABYLON.PointLight) {
  136. // Point Light
  137. light.transferToEffect(effect, "vLightData" + lightIndex);
  138. }
  139. else if (light instanceof BABYLON.DirectionalLight) {
  140. // Directional Light
  141. light.transferToEffect(effect, "vLightData" + lightIndex);
  142. }
  143. else if (light instanceof BABYLON.SpotLight) {
  144. // Spot Light
  145. light.transferToEffect(effect, "vLightData" + lightIndex, "vLightDirection" + lightIndex);
  146. }
  147. else if (light instanceof BABYLON.HemisphericLight) {
  148. // Hemispheric Light
  149. light.transferToEffect(effect, "vLightData" + lightIndex, "vLightGround" + lightIndex);
  150. }
  151. };
  152. MaterialHelper.BindLights = function (scene, mesh, effect, defines) {
  153. var lightIndex = 0;
  154. var depthValuesAlreadySet = false;
  155. for (var index = 0; index < scene.lights.length; index++) {
  156. var light = scene.lights[index];
  157. if (!light.isEnabled()) {
  158. continue;
  159. }
  160. if (!light.canAffectMesh(mesh)) {
  161. continue;
  162. }
  163. MaterialHelper.BindLightProperties(light, effect, lightIndex);
  164. light.diffuse.scaleToRef(light.intensity, BABYLON.Tmp.Color3[0]);
  165. effect.setColor4("vLightDiffuse" + lightIndex, BABYLON.Tmp.Color3[0], light.range);
  166. if (defines["SPECULARTERM"]) {
  167. light.specular.scaleToRef(light.intensity, BABYLON.Tmp.Color3[1]);
  168. effect.setColor3("vLightSpecular" + lightIndex, BABYLON.Tmp.Color3[1]);
  169. }
  170. // Shadows
  171. if (scene.shadowsEnabled) {
  172. depthValuesAlreadySet = this.BindLightShadow(light, scene, mesh, lightIndex, effect, depthValuesAlreadySet);
  173. }
  174. lightIndex++;
  175. if (lightIndex === maxSimultaneousLights)
  176. break;
  177. }
  178. };
  179. MaterialHelper.BindFogParameters = function (scene, mesh, effect) {
  180. if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
  181. effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
  182. effect.setColor3("vFogColor", scene.fogColor);
  183. }
  184. };
  185. MaterialHelper.BindBonesParameters = function (mesh, effect) {
  186. if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
  187. effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
  188. }
  189. };
  190. MaterialHelper.BindLogDepth = function (defines, effect, scene) {
  191. if (defines["LOGARITHMICDEPTH"]) {
  192. effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
  193. }
  194. };
  195. MaterialHelper.BindClipPlane = function (effect, scene) {
  196. if (scene.clipPlane) {
  197. var clipPlane = scene.clipPlane;
  198. effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
  199. }
  200. };
  201. return MaterialHelper;
  202. }());
  203. BABYLON.MaterialHelper = MaterialHelper;
  204. })(BABYLON || (BABYLON = {}));