PageRenderTime 53ms CodeModel.GetById 20ms app.highlight 12ms RepoModel.GetById 18ms app.codeStats 0ms

/src/away3d/materials/methods/RimLightMethod.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 172 lines | 113 code | 21 blank | 38 comment | 8 complexity | d7ea56dfa0b04d722c192599f6645321 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	
  8	use namespace arcane;
  9
 10	/**
 11	 * RimLightMethod provides a method to add rim lighting to a material. This adds a glow-like effect to edges of objects.
 12	 */
 13	public class RimLightMethod extends EffectMethodBase
 14	{
 15		public static const ADD:String = "add";
 16		public static const MULTIPLY:String = "multiply";
 17		public static const MIX:String = "mix";
 18		
 19		private var _color:uint;
 20		private var _blendMode:String;
 21		private var _colorR:Number;
 22		private var _colorG:Number;
 23		private var _colorB:Number;
 24		private var _strength:Number;
 25		private var _power:Number;
 26
 27		/**
 28		 * Creates a new RimLightMethod.
 29		 * @param color The colour of the rim light.
 30		 * @param strength The strength of the rim light.
 31		 * @param power The power of the rim light. Higher values will result in a higher edge fall-off.
 32		 * @param blend The blend mode with which to add the light to the object.
 33		 */
 34		public function RimLightMethod(color:uint = 0xffffff, strength:Number = .4, power:Number = 2, blend:String = "mix")
 35		{
 36			super();
 37			_blendMode = blend;
 38			_strength = strength;
 39			_power = power;
 40			this.color = color;
 41		}
 42
 43		/**
 44		 * @inheritDoc
 45		 */
 46		override arcane function initConstants(vo:MethodVO):void
 47		{
 48			vo.fragmentData[vo.fragmentConstantsIndex + 3] = 1;
 49		}
 50
 51		/**
 52		 * @inheritDoc
 53		 */
 54		override arcane function initVO(vo:MethodVO):void
 55		{
 56			vo.needsNormals = true;
 57			vo.needsView = true;
 58		}
 59
 60
 61		/**
 62		 * The blend mode with which to add the light to the object.
 63		 *
 64		 * RimLightMethod.MULTIPLY multiplies the rim light with the material's colour.
 65		 * RimLightMethod.ADD adds the rim light with the material's colour.
 66		 * RimLightMethod.MIX provides normal alpha blending.
 67		 */
 68		public function get blendMode() : String
 69		{
 70			return _blendMode;
 71		}
 72
 73		public function set blendMode(value : String) : void
 74		{
 75			if (_blendMode == value) return;
 76			_blendMode = value;
 77			invalidateShaderProgram();
 78		}
 79
 80		/**
 81		 * The color of the rim light.
 82		 */
 83		public function get color():uint
 84		{
 85			return _color;
 86		}
 87		
 88		public function set color(value:uint):void
 89		{
 90			_color = value;
 91			_colorR = ((value >> 16) & 0xff)/0xff;
 92			_colorG = ((value >> 8) & 0xff)/0xff;
 93			_colorB = (value & 0xff)/0xff;
 94		}
 95
 96		/**
 97		 * The strength of the rim light.
 98		 */
 99		public function get strength():Number
100		{
101			return _strength;
102		}
103		
104		public function set strength(value:Number):void
105		{
106			_strength = value;
107		}
108
109		/**
110		 * The power of the rim light. Higher values will result in a higher edge fall-off.
111		 */
112		public function get power():Number
113		{
114			return _power;
115		}
116		
117		public function set power(value:Number):void
118		{
119			_power = value;
120		}
121
122		/**
123		 * @inheritDoc
124		 */
125		arcane override function activate(vo:MethodVO, stage3DProxy:Stage3DProxy):void
126		{
127			var index:int = vo.fragmentConstantsIndex;
128			var data:Vector.<Number> = vo.fragmentData;
129			data[index] = _colorR;
130			data[index + 1] = _colorG;
131			data[index + 2] = _colorB;
132			data[index + 4] = _strength;
133			data[index + 5] = _power;
134		}
135
136		/**
137		 * @inheritDoc
138		 */
139		arcane override function getFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, targetReg:ShaderRegisterElement):String
140		{
141			var dataRegister:ShaderRegisterElement = regCache.getFreeFragmentConstant();
142			var dataRegister2:ShaderRegisterElement = regCache.getFreeFragmentConstant();
143			var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
144			var code:String = "";
145			
146			vo.fragmentConstantsIndex = dataRegister.index*4;
147			
148			code += "dp3 " + temp + ".x, " + _sharedRegisters.viewDirFragment + ".xyz, " + _sharedRegisters.normalFragment + ".xyz	\n" +
149				"sat " + temp + ".x, " + temp + ".x														\n" +
150				"sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x								\n" +
151				"pow " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".y							\n" +
152				"mul " + temp + ".x, " + temp + ".x, " + dataRegister2 + ".x							\n" +
153				"sub " + temp + ".x, " + dataRegister + ".w, " + temp + ".x								\n" +
154				"mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".x						\n" +
155				"sub " + temp + ".w, " + dataRegister + ".w, " + temp + ".x								\n";
156			
157			if (_blendMode == ADD) {
158				code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz							\n" +
159					"add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz						\n";
160			} else if (_blendMode == MULTIPLY) {
161				code += "mul " + temp + ".xyz, " + temp + ".w, " + dataRegister + ".xyz							\n" +
162					"mul " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz						\n";
163			} else {
164				code += "sub " + temp + ".xyz, " + dataRegister + ".xyz, " + targetReg + ".xyz				\n" +
165					"mul " + temp + ".xyz, " + temp + ".xyz, " + temp + ".w								\n" +
166					"add " + targetReg + ".xyz, " + targetReg + ".xyz, " + temp + ".xyz					\n";
167			}
168			
169			return code;
170		}
171	}
172}