PageRenderTime 264ms CodeModel.GetById 131ms app.highlight 11ms RepoModel.GetById 119ms app.codeStats 1ms

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