PageRenderTime 283ms CodeModel.GetById 141ms app.highlight 9ms RepoModel.GetById 131ms app.codeStats 0ms

/src/away3d/materials/methods/EnvMapMethod.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 145 lines | 96 code | 19 blank | 30 comment | 10 complexity | d688179283ce69391ed55c5af7dbf780 MD5 | raw file
  1package away3d.materials.methods
  2{
  3	import away3d.arcane;
  4	import away3d.core.managers.Stage3DProxy;
  5	import away3d.materials.compilation.ShaderRegisterCache;
  6	import away3d.materials.compilation.ShaderRegisterElement;
  7	import away3d.textures.CubeTextureBase;
  8	import away3d.textures.Texture2DBase;
  9	
 10	import flash.display3D.Context3D;
 11	
 12	use namespace arcane;
 13
 14	/**
 15	 * EnvMapMethod provides a material method to perform reflection mapping using cube maps.
 16	 */
 17	public class EnvMapMethod extends EffectMethodBase
 18	{
 19		private var _cubeTexture:CubeTextureBase;
 20		private var _alpha:Number;
 21		private var _mask:Texture2DBase;
 22
 23		/**
 24		 * Creates an EnvMapMethod object.
 25		 * @param envMap The environment map containing the reflected scene.
 26		 * @param alpha The reflectivity of the surface.
 27		 */
 28		public function EnvMapMethod(envMap:CubeTextureBase, alpha:Number = 1)
 29		{
 30			super();
 31			_cubeTexture = envMap;
 32			_alpha = alpha;
 33		}
 34
 35		/**
 36		 * An optional texture to modulate the reflectivity of the surface.
 37		 */
 38		public function get mask():Texture2DBase
 39		{
 40			return _mask;
 41		}
 42		
 43		public function set mask(value:Texture2DBase):void
 44		{
 45			if (Boolean(value) != Boolean(_mask) ||
 46				(value && _mask && (value.hasMipMaps != _mask.hasMipMaps || value.format != _mask.format))) {
 47				invalidateShaderProgram();
 48			}
 49			_mask = value;
 50		}
 51
 52		/**
 53		 * @inheritDoc
 54		 */
 55		override arcane function initVO(vo:MethodVO):void
 56		{
 57			vo.needsNormals = true;
 58			vo.needsView = true;
 59			vo.needsUV = _mask != null;
 60		}
 61		
 62		/**
 63		 * The cubic environment map containing the reflected scene.
 64		 */
 65		public function get envMap():CubeTextureBase
 66		{
 67			return _cubeTexture;
 68		}
 69		
 70		public function set envMap(value:CubeTextureBase):void
 71		{
 72			_cubeTexture = value;
 73		}
 74		
 75		/**
 76		 * @inheritDoc
 77		 */
 78		override public function dispose():void
 79		{
 80		}
 81		
 82		/**
 83		 * The reflectivity of the surface.
 84		 */
 85		public function get alpha():Number
 86		{
 87			return _alpha;
 88		}
 89		
 90		public function set alpha(value:Number):void
 91		{
 92			_alpha = value;
 93		}
 94
 95		/**
 96		 * @inheritDoc
 97		 */
 98		arcane override function activate(vo:MethodVO, stage3DProxy:Stage3DProxy):void
 99		{
100			var context:Context3D = stage3DProxy._context3D;
101			vo.fragmentData[vo.fragmentConstantsIndex] = _alpha;
102			context.setTextureAt(vo.texturesIndex, _cubeTexture.getTextureForStage3D(stage3DProxy));
103			if (_mask)
104				context.setTextureAt(vo.texturesIndex + 1, _mask.getTextureForStage3D(stage3DProxy));
105		}
106
107		/**
108		 * @inheritDoc
109		 */
110		arcane override function getFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, targetReg:ShaderRegisterElement):String
111		{
112			var dataRegister:ShaderRegisterElement = regCache.getFreeFragmentConstant();
113			var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
114			var code:String = "";
115			var cubeMapReg:ShaderRegisterElement = regCache.getFreeTextureReg();
116			vo.texturesIndex = cubeMapReg.index;
117			vo.fragmentConstantsIndex = dataRegister.index*4;
118			
119			regCache.addFragmentTempUsages(temp, 1);
120			var temp2:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
121			
122			// r = I - 2(I.N)*N
123			code += "dp3 " + temp + ".w, " + _sharedRegisters.viewDirFragment + ".xyz, " + _sharedRegisters.normalFragment + ".xyz		\n" +
124				"add " + temp + ".w, " + temp + ".w, " + temp + ".w											\n" +
125				"mul " + temp + ".xyz, " + _sharedRegisters.normalFragment + ".xyz, " + temp + ".w						\n" +
126				"sub " + temp + ".xyz, " + temp + ".xyz, " + _sharedRegisters.viewDirFragment + ".xyz					\n" +
127				getTexCubeSampleCode(vo, temp, cubeMapReg, _cubeTexture, temp) +
128				"sub " + temp2 + ".w, " + temp + ".w, fc0.x									\n" +               	// -.5
129				"kil " + temp2 + ".w\n" +	// used for real time reflection mapping - if alpha is not 1 (mock texture) kil output
130				"sub " + temp + ", " + temp + ", " + targetReg + "											\n";
131			
132			if (_mask) {
133				var maskReg:ShaderRegisterElement = regCache.getFreeTextureReg();
134				code += getTex2DSampleCode(vo, temp2, maskReg, _mask, _sharedRegisters.uvVarying) +
135					"mul " + temp + ", " + temp2 + ", " + temp + "\n";
136			}
137			code += "mul " + temp + ", " + temp + ", " + dataRegister + ".x										\n" +
138				"add " + targetReg + ", " + targetReg + ", " + temp + "										\n";
139			
140			regCache.removeFragmentTempUsage(temp);
141			
142			return code;
143		}
144	}
145}