/src/away3d/materials/passes/SingleObjectDepthPass.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 193 lines · 122 code · 24 blank · 47 comment · 10 complexity · fea7b951cea313d70bcc6847a1c6f60e 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.lights.LightBase;
  8. import flash.display3D.Context3D;
  9. import flash.display3D.Context3DProgramType;
  10. import flash.display3D.Context3DTextureFormat;
  11. import flash.display3D.textures.Texture;
  12. import flash.geom.Matrix3D;
  13. import flash.utils.Dictionary;
  14. use namespace arcane;
  15. /**
  16. * The SingleObjectDepthPass provides a material pass that renders a single object to a depth map from the point
  17. * of view from a light.
  18. */
  19. public class SingleObjectDepthPass extends MaterialPassBase
  20. {
  21. private var _textures:Vector.<Dictionary>;
  22. private var _projections:Dictionary;
  23. private var _textureSize:uint;
  24. private var _polyOffset:Vector.<Number>;
  25. private var _enc:Vector.<Number>;
  26. private var _projectionTexturesInvalid:Boolean = true;
  27. /**
  28. * Creates a new SingleObjectDepthPass object.
  29. * @param textureSize The size of the depth map texture to render to.
  30. * @param polyOffset The amount by which the rendered object will be inflated, to prevent depth map rounding errors.
  31. *
  32. * todo: provide custom vertex code to assembler
  33. */
  34. public function SingleObjectDepthPass(textureSize:uint = 512, polyOffset:Number = 15)
  35. {
  36. super(true);
  37. _textureSize = textureSize;
  38. _numUsedStreams = 2;
  39. _numUsedVertexConstants = 7;
  40. _polyOffset = new <Number>[polyOffset, 0, 0, 0];
  41. _enc = Vector.<Number>([ 1.0, 255.0, 65025.0, 16581375.0,
  42. 1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0
  43. ]);
  44. _animatableAttributes = Vector.<String>(["va0", "va1"]);
  45. _animationTargetRegisters = Vector.<String>(["vt0", "vt1"]);
  46. }
  47. /**
  48. * @inheritDoc
  49. */
  50. override public function dispose():void
  51. {
  52. if (_textures) {
  53. for (var i:uint = 0; i < _textures.length; ++i) {
  54. for each (var vec:Vector.<Texture> in _textures[i]) {
  55. for (var j:uint = 0; j < vec.length; ++j)
  56. vec[j].dispose();
  57. }
  58. }
  59. _textures = null;
  60. }
  61. }
  62. /**
  63. * Updates the projection textures used to contain the depth renders.
  64. */
  65. private function updateProjectionTextures():void
  66. {
  67. if (_textures) {
  68. for (var i:uint = 0; i < _textures.length; ++i) {
  69. for each (var vec:Vector.<Texture> in _textures[i]) {
  70. for (var j:uint = 0; j < vec.length; ++j)
  71. vec[j].dispose();
  72. }
  73. }
  74. }
  75. _textures = new Vector.<Dictionary>(8);
  76. _projections = new Dictionary();
  77. _projectionTexturesInvalid = false;
  78. }
  79. /**
  80. * @inheritDoc
  81. */
  82. arcane override function getVertexCode():String
  83. {
  84. var code:String;
  85. // offset
  86. code = "mul vt7, vt1, vc4.x \n" +
  87. "add vt7, vt7, vt0 \n" +
  88. "mov vt7.w, vt0.w \n";
  89. // project
  90. code += "m44 vt2, vt7, vc0 \n" +
  91. "mov op, vt2 \n";
  92. // perspective divide
  93. code += "div v0, vt2, vt2.w \n";
  94. return code;
  95. }
  96. /**
  97. * @inheritDoc
  98. */
  99. arcane override function getFragmentCode(animationCode:String):String
  100. {
  101. var code:String = "";
  102. // encode float -> rgba
  103. code += "mul ft0, fc0, v0.z \n" +
  104. "frc ft0, ft0 \n" +
  105. "mul ft1, ft0.yzww, fc1 \n" +
  106. "sub ft0, ft0, ft1 \n" +
  107. "mov oc, ft0 \n";
  108. return code;
  109. }
  110. /**
  111. * Gets the depth maps rendered for this object from all lights.
  112. * @param renderable The renderable for which to retrieve the depth maps.
  113. * @param stage3DProxy The Stage3DProxy object currently used for rendering.
  114. * @return A list of depth map textures for all supported lights.
  115. */
  116. arcane function getDepthMap(renderable:IRenderable, stage3DProxy:Stage3DProxy):Texture
  117. {
  118. return _textures[stage3DProxy._stage3DIndex][renderable];
  119. }
  120. /**
  121. * Retrieves the depth map projection maps for all lights.
  122. * @param renderable The renderable for which to retrieve the projection maps.
  123. * @return A list of projection maps for all supported lights.
  124. */
  125. arcane function getProjection(renderable:IRenderable):Matrix3D
  126. {
  127. return _projections[renderable];
  128. }
  129. /**
  130. * @inheritDoc
  131. */
  132. arcane override function render(renderable:IRenderable, stage3DProxy:Stage3DProxy, camera:Camera3D, viewProjection:Matrix3D):void
  133. {
  134. var matrix:Matrix3D;
  135. var contextIndex:int = stage3DProxy._stage3DIndex;
  136. var context:Context3D = stage3DProxy._context3D;
  137. var len:uint;
  138. var light:LightBase;
  139. var lights:Vector.<LightBase> = _lightPicker.allPickedLights;
  140. _textures[contextIndex] ||= new Dictionary();
  141. if (!_projections[renderable])
  142. _projections[renderable] = new Matrix3D();
  143. len = lights.length;
  144. // local position = enough
  145. light = lights[0];
  146. matrix = light.getObjectProjectionMatrix(renderable, camera, _projections[renderable]);
  147. // todo: use texture proxy?
  148. var target:Texture = _textures[contextIndex][renderable] ||= context.createTexture(_textureSize, _textureSize, Context3DTextureFormat.BGRA, true);
  149. stage3DProxy.setRenderTarget(target, true);
  150. context.clear(1.0, 1.0, 1.0);
  151. context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, matrix, true);
  152. context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _enc, 2);
  153. renderable.activateVertexBuffer(0, stage3DProxy);
  154. renderable.activateVertexNormalBuffer(1, stage3DProxy);
  155. context.drawTriangles(renderable.getIndexBuffer(stage3DProxy), 0, renderable.numTriangles);
  156. }
  157. /**
  158. * @inheritDoc
  159. */
  160. override arcane function activate(stage3DProxy:Stage3DProxy, camera:Camera3D):void
  161. {
  162. if (_projectionTexturesInvalid)
  163. updateProjectionTextures();
  164. // never scale
  165. super.activate(stage3DProxy, camera);
  166. stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, _polyOffset, 1);
  167. }
  168. }
  169. }