/src/away3d/materials/passes/DepthMapPass.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 176 lines · 123 code · 24 blank · 29 comment · 17 complexity · 60b57a13293217fc5a857520acaca267 MD5 · raw file

  1. package away3d.materials.passes
  2. {
  3. import away3d.arcane;
  4. import away3d.cameras.Camera3D;
  5. import away3d.core.base.IRenderable;
  6. import away3d.core.managers.Stage3DProxy;
  7. import away3d.core.math.Matrix3DUtils;
  8. import away3d.textures.Texture2DBase;
  9. import flash.display3D.Context3D;
  10. import flash.display3D.Context3DProgramType;
  11. import flash.display3D.Context3DTextureFormat;
  12. import flash.geom.Matrix3D;
  13. use namespace arcane;
  14. /**
  15. * DepthMapPass is a pass that writes depth values to a depth map as a 32-bit value exploded over the 4 texture channels.
  16. * This is used to render shadow maps, depth maps, etc.
  17. */
  18. public class DepthMapPass extends MaterialPassBase
  19. {
  20. private var _data:Vector.<Number>;
  21. private var _alphaThreshold:Number = 0;
  22. private var _alphaMask:Texture2DBase;
  23. /**
  24. * Creates a new DepthMapPass object.
  25. */
  26. public function DepthMapPass()
  27. {
  28. super();
  29. _data = Vector.<Number>([ 1.0, 255.0, 65025.0, 16581375.0,
  30. 1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0,
  31. 0.0, 0.0, 0.0, 0.0]);
  32. }
  33. /**
  34. * The minimum alpha value for which pixels should be drawn. This is used for transparency that is either
  35. * invisible or entirely opaque, often used with textures for foliage, etc.
  36. * Recommended values are 0 to disable alpha, or 0.5 to create smooth edges. Default value is 0 (disabled).
  37. */
  38. public function get alphaThreshold():Number
  39. {
  40. return _alphaThreshold;
  41. }
  42. public function set alphaThreshold(value:Number):void
  43. {
  44. if (value < 0)
  45. value = 0;
  46. else if (value > 1)
  47. value = 1;
  48. if (value == _alphaThreshold)
  49. return;
  50. if (value == 0 || _alphaThreshold == 0)
  51. invalidateShaderProgram();
  52. _alphaThreshold = value;
  53. _data[8] = _alphaThreshold;
  54. }
  55. /**
  56. * A texture providing alpha data to be able to prevent semi-transparent pixels to write to the alpha mask.
  57. * Usually the diffuse texture when alphaThreshold is used.
  58. */
  59. public function get alphaMask():Texture2DBase
  60. {
  61. return _alphaMask;
  62. }
  63. public function set alphaMask(value:Texture2DBase):void
  64. {
  65. _alphaMask = value;
  66. }
  67. /**
  68. * @inheritDoc
  69. */
  70. arcane override function getVertexCode():String
  71. {
  72. var code:String;
  73. // project
  74. code = "m44 vt1, vt0, vc0 \n" +
  75. "mov op, vt1 \n";
  76. if (_alphaThreshold > 0) {
  77. _numUsedTextures = 1;
  78. _numUsedStreams = 2;
  79. code += "mov v0, vt1\n" +
  80. "mov v1, va1\n";
  81. } else {
  82. _numUsedTextures = 0;
  83. _numUsedStreams = 1;
  84. code += "mov v0, vt1\n";
  85. }
  86. return code;
  87. }
  88. /**
  89. * @inheritDoc
  90. */
  91. arcane override function getFragmentCode(code:String):String
  92. {
  93. var codeF:String =
  94. "div ft2, v0, v0.w \n" +
  95. "mul ft0, fc0, ft2.z \n" +
  96. "frc ft0, ft0 \n" +
  97. "mul ft1, ft0.yzww, fc1 \n";
  98. if (_alphaThreshold > 0) {
  99. var wrap:String = _repeat ? "wrap" : "clamp";
  100. var filter:String, format:String;
  101. var enableMipMaps:Boolean = _mipmap && _alphaMask.hasMipMaps;
  102. if (_smooth)
  103. filter = enableMipMaps ? "linear,miplinear" : "linear";
  104. else
  105. filter = enableMipMaps ? "nearest,mipnearest" : "nearest";
  106. switch (_alphaMask.format) {
  107. case Context3DTextureFormat.COMPRESSED:
  108. format = "dxt1,";
  109. break;
  110. case "compressedAlpha":
  111. format = "dxt5,";
  112. break;
  113. default:
  114. format = "";
  115. }
  116. codeF += "tex ft3, v1, fs0 <2d," + filter + "," + format + wrap + ">\n" +
  117. "sub ft3.w, ft3.w, fc2.x\n" +
  118. "kil ft3.w\n";
  119. }
  120. codeF += "sub oc, ft0, ft1 \n";
  121. return codeF;
  122. }
  123. /**
  124. * @inheritDoc
  125. */
  126. arcane override function render(renderable:IRenderable, stage3DProxy:Stage3DProxy, camera:Camera3D, viewProjection:Matrix3D):void
  127. {
  128. if (_alphaThreshold > 0)
  129. renderable.activateUVBuffer(1, stage3DProxy);
  130. var context:Context3D = stage3DProxy._context3D;
  131. var matrix:Matrix3D = Matrix3DUtils.CALCULATION_MATRIX;
  132. matrix.copyFrom(renderable.getRenderSceneTransform(camera));
  133. matrix.append(viewProjection);
  134. context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, matrix, true);
  135. renderable.activateVertexBuffer(0, stage3DProxy);
  136. context.drawTriangles(renderable.getIndexBuffer(stage3DProxy), 0, renderable.numTriangles);
  137. }
  138. /**
  139. * @inheritDoc
  140. */
  141. override arcane function activate(stage3DProxy:Stage3DProxy, camera:Camera3D):void
  142. {
  143. var context:Context3D = stage3DProxy._context3D;
  144. super.activate(stage3DProxy, camera);
  145. if (_alphaThreshold > 0) {
  146. context.setTextureAt(0, _alphaMask.getTextureForStage3D(stage3DProxy));
  147. context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _data, 3);
  148. } else
  149. context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _data, 2);
  150. }
  151. }
  152. }