babylon.outlineRenderer.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. module BABYLON {
  2. export class OutlineRenderer {
  3. private _scene: Scene;
  4. private _effect: Effect;
  5. private _cachedDefines: string;
  6. public zOffset = 1;
  7. constructor(scene: Scene) {
  8. this._scene = scene;
  9. }
  10. public render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay: boolean = false) {
  11. var scene = this._scene;
  12. var engine = this._scene.getEngine();
  13. var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
  14. if (!this.isReady(subMesh, hardwareInstancedRendering)) {
  15. return;
  16. }
  17. var mesh = subMesh.getRenderingMesh();
  18. var material = subMesh.getMaterial();
  19. engine.enableEffect(this._effect);
  20. // Logarithmic depth
  21. if((<any> material).useLogarithmicDepth)
  22. {
  23. this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
  24. }
  25. this._effect.setFloat("offset", useOverlay ? 0 : mesh.outlineWidth);
  26. this._effect.setColor4("color", useOverlay ? mesh.overlayColor : mesh.outlineColor, useOverlay ? mesh.overlayAlpha : material.alpha);
  27. this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
  28. // Bones
  29. if (mesh.useBones && mesh.computeBonesUsingShaders) {
  30. this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
  31. }
  32. mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
  33. // Alpha test
  34. if (material && material.needAlphaTesting()) {
  35. var alphaTexture = material.getAlphaTestTexture();
  36. if (alphaTexture) {
  37. this._effect.setTexture("diffuseSampler", alphaTexture);
  38. this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
  39. }
  40. }
  41. engine.setZOffset(-this.zOffset);
  42. mesh._processRendering(subMesh, this._effect, Material.TriangleFillMode, batch, hardwareInstancedRendering,
  43. (isInstance, world) => { this._effect.setMatrix("world", world) });
  44. engine.setZOffset(0);
  45. }
  46. public isReady(subMesh: SubMesh, useInstances: boolean): boolean {
  47. var defines = [];
  48. var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
  49. var mesh = subMesh.getMesh();
  50. var material = subMesh.getMaterial();
  51. if (material) {
  52. // Alpha test
  53. if(material.needAlphaTesting())
  54. {
  55. defines.push("#define ALPHATEST");
  56. if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
  57. attribs.push(VertexBuffer.UVKind);
  58. defines.push("#define UV1");
  59. }
  60. if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
  61. attribs.push(VertexBuffer.UV2Kind);
  62. defines.push("#define UV2");
  63. }
  64. }
  65. //Logarithmic depth
  66. if((<any> material).useLogarithmicDepth)
  67. {
  68. defines.push("#define LOGARITHMICDEPTH");
  69. }
  70. }
  71. // Bones
  72. if (mesh.useBones && mesh.computeBonesUsingShaders) {
  73. attribs.push(VertexBuffer.MatricesIndicesKind);
  74. attribs.push(VertexBuffer.MatricesWeightsKind);
  75. if (mesh.numBoneInfluencers > 4) {
  76. attribs.push(VertexBuffer.MatricesIndicesExtraKind);
  77. attribs.push(VertexBuffer.MatricesWeightsExtraKind);
  78. }
  79. defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
  80. defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
  81. } else {
  82. defines.push("#define NUM_BONE_INFLUENCERS 0");
  83. }
  84. // Instances
  85. if (useInstances) {
  86. defines.push("#define INSTANCES");
  87. attribs.push("world0");
  88. attribs.push("world1");
  89. attribs.push("world2");
  90. attribs.push("world3");
  91. }
  92. // Get correct effect
  93. var join = defines.join("\n");
  94. if (this._cachedDefines !== join) {
  95. this._cachedDefines = join;
  96. this._effect = this._scene.getEngine().createEffect("outline",
  97. attribs,
  98. ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"],
  99. ["diffuseSampler"], join);
  100. }
  101. return this._effect.isReady();
  102. }
  103. }
  104. }