PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/away3d/materials/passes/DefaultScreenPass.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 1550 lines | 1182 code | 252 blank | 116 comment | 204 complexity | 899631cc92e582f6f1123e2fb8fa8517 MD5 | raw file
Possible License(s): Apache-2.0
  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.events.ShadingMethodEvent;
  8. import away3d.lights.DirectionalLight;
  9. import away3d.lights.LightProbe;
  10. import away3d.lights.PointLight;
  11. import away3d.materials.LightSources;
  12. import away3d.materials.MaterialBase;
  13. import away3d.materials.lightpickers.LightPickerBase;
  14. import away3d.materials.methods.BasicAmbientMethod;
  15. import away3d.materials.methods.BasicDiffuseMethod;
  16. import away3d.materials.methods.BasicNormalMethod;
  17. import away3d.materials.methods.BasicSpecularMethod;
  18. import away3d.materials.methods.ColorTransformMethod;
  19. import away3d.materials.methods.EffectMethodBase;
  20. import away3d.materials.methods.MethodVO;
  21. import away3d.materials.methods.ShadingMethodBase;
  22. import away3d.materials.methods.ShadowMapMethodBase;
  23. import away3d.materials.utils.ShaderRegisterCache;
  24. import away3d.materials.utils.ShaderRegisterElement;
  25. import away3d.textures.Texture2DBase;
  26. import flash.display3D.Context3D;
  27. import flash.display3D.Context3DProgramType;
  28. import flash.display3D.Context3DVertexBufferFormat;
  29. import flash.geom.ColorTransform;
  30. import flash.geom.Matrix;
  31. import flash.geom.Vector3D;
  32. use namespace arcane;
  33. /**
  34. * DefaultScreenPass is a shader pass that uses shader methods to compile a complete program.
  35. *
  36. * @see away3d.materials.methods.ShadingMethodBase
  37. */
  38. // TODO: Remove compilation from this class, gets messy. Only perform rendering here.
  39. public class DefaultScreenPass extends MaterialPassBase
  40. {
  41. // private var _cameraPositionData : Vector.<Number> = Vector.<Number>([0, 0, 0, 1]);
  42. // private var _lightData : Vector.<Number>;
  43. // private var _uvTransformData : Vector.<Number>;
  44. // todo: create something similar for diffuse: useOnlyProbesDiffuse - ignoring normal lights?
  45. // or: for both, provide mode: LightSourceMode.LIGHTS = 0x01, LightSourceMode.PROBES = 0x02, LightSourceMode.ALL = 0x03
  46. private var _specularLightSources : uint = 0x01;
  47. private var _diffuseLightSources : uint = 0x03;
  48. private var _combinedLightSources : uint;
  49. private var _colorTransformMethod : ColorTransformMethod;
  50. private var _colorTransformMethodVO : MethodVO;
  51. private var _normalMethod : BasicNormalMethod;
  52. private var _normalMethodVO : MethodVO;
  53. private var _ambientMethod : BasicAmbientMethod;
  54. private var _ambientMethodVO : MethodVO;
  55. private var _shadowMethod : ShadowMapMethodBase;
  56. private var _shadowMethodVO : MethodVO;
  57. private var _diffuseMethod : BasicDiffuseMethod;
  58. private var _diffuseMethodVO : MethodVO;
  59. private var _specularMethod : BasicSpecularMethod;
  60. private var _specularMethodVO : MethodVO;
  61. private var _methods : Vector.<MethodSet>;
  62. private var _registerCache : ShaderRegisterCache;
  63. private var _vertexCode : String;
  64. private var _fragmentCode : String;
  65. private var _projectionDependencies : uint;
  66. private var _normalDependencies : uint;
  67. private var _viewDirDependencies : uint;
  68. private var _uvDependencies : uint;
  69. private var _secondaryUVDependencies : uint;
  70. private var _globalPosDependencies : uint;
  71. // registers
  72. protected var _uvBufferIndex : int;
  73. protected var _secondaryUVBufferIndex : int;
  74. protected var _normalBufferIndex : int;
  75. protected var _tangentBufferIndex : int;
  76. protected var _sceneMatrixIndex : int;
  77. protected var _sceneNormalMatrixIndex : int;
  78. protected var _lightDataIndex : int;
  79. protected var _cameraPositionIndex : int;
  80. protected var _uvTransformIndex : int;
  81. private var _projectionFragmentReg : ShaderRegisterElement;
  82. private var _normalFragmentReg : ShaderRegisterElement;
  83. private var _viewDirFragmentReg : ShaderRegisterElement;
  84. private var _lightInputIndices : Vector.<uint>;
  85. private var _lightProbeDiffuseIndices : Vector.<uint>;
  86. private var _lightProbeSpecularIndices : Vector.<uint>;
  87. private var _normalVarying : ShaderRegisterElement;
  88. private var _tangentVarying : ShaderRegisterElement;
  89. private var _bitangentVarying : ShaderRegisterElement;
  90. private var _uvVaryingReg : ShaderRegisterElement;
  91. private var _secondaryUVVaryingReg : ShaderRegisterElement;
  92. private var _viewDirVaryingReg : ShaderRegisterElement;
  93. private var _shadedTargetReg : ShaderRegisterElement;
  94. private var _globalPositionVertexReg : ShaderRegisterElement;
  95. private var _globalPositionVaryingReg : ShaderRegisterElement;
  96. private var _localPositionRegister : ShaderRegisterElement;
  97. private var _positionMatrixRegs : Vector.<ShaderRegisterElement>;
  98. private var _normalInput : ShaderRegisterElement;
  99. private var _tangentInput : ShaderRegisterElement;
  100. private var _animatedNormalReg : ShaderRegisterElement;
  101. private var _animatedTangentReg : ShaderRegisterElement;
  102. private var _commonsReg : ShaderRegisterElement;
  103. private var _commonsDataIndex : int;
  104. // private var _commonsData : Vector.<Number> = Vector.<Number>([.5, 0, 0, 1]);
  105. private var _vertexConstantIndex : uint;
  106. private var _vertexConstantData : Vector.<Number> = new Vector.<Number>();
  107. private var _fragmentConstantData : Vector.<Number> = new Vector.<Number>();
  108. arcane var _passes : Vector.<MaterialPassBase>;
  109. arcane var _passesDirty : Boolean;
  110. private var _animateUVs : Boolean;
  111. private var _numLights : int;
  112. private var _lightDataLength : int;
  113. private var _pointLightRegisters : Vector.<ShaderRegisterElement>;
  114. private var _dirLightRegisters : Vector.<ShaderRegisterElement>;
  115. private var _diffuseLightIndex : int;
  116. private var _specularLightIndex : int;
  117. private var _probeWeightsIndex : int;
  118. private var _numProbeRegisters : uint;
  119. private var _usingSpecularMethod : Boolean;
  120. private var _usesGlobalPosFragment : Boolean = true;
  121. private var _tangentDependencies : int;
  122. private var _ambientLightR : Number;
  123. private var _ambientLightG : Number;
  124. private var _ambientLightB : Number;
  125. private var _projectedTargetRegister : String;
  126. /**
  127. * Creates a new DefaultScreenPass objects.
  128. */
  129. public function DefaultScreenPass(material : MaterialBase)
  130. {
  131. super();
  132. _material = material;
  133. init();
  134. }
  135. private function init() : void
  136. {
  137. _methods = new Vector.<MethodSet>();
  138. _normalMethod = new BasicNormalMethod();
  139. _ambientMethod = new BasicAmbientMethod();
  140. _diffuseMethod = new BasicDiffuseMethod();
  141. _specularMethod = new BasicSpecularMethod();
  142. _normalMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  143. _diffuseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  144. _specularMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  145. _ambientMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  146. _normalMethodVO = _normalMethod.createMethodVO();
  147. _ambientMethodVO = _ambientMethod.createMethodVO();
  148. _diffuseMethodVO = _diffuseMethod.createMethodVO();
  149. _specularMethodVO = _specularMethod.createMethodVO();
  150. }
  151. public function get animateUVs() : Boolean
  152. {
  153. return _animateUVs;
  154. }
  155. public function set animateUVs(value : Boolean) : void
  156. {
  157. _animateUVs = value;
  158. if ((value && !_animateUVs) || (!value && _animateUVs)) invalidateShaderProgram();
  159. }
  160. /**
  161. * @inheritDoc
  162. */
  163. override public function set mipmap(value : Boolean) : void
  164. {
  165. if (_mipmap == value) return;
  166. super.mipmap = value;
  167. }
  168. public function get specularLightSources() : uint
  169. {
  170. return _specularLightSources;
  171. }
  172. public function set specularLightSources(value : uint) : void
  173. {
  174. _specularLightSources = value;
  175. }
  176. public function get diffuseLightSources() : uint
  177. {
  178. return _diffuseLightSources;
  179. }
  180. public function set diffuseLightSources(value : uint) : void
  181. {
  182. _diffuseLightSources = value;
  183. }
  184. /**
  185. * The ColorTransform object to transform the colour of the material with.
  186. */
  187. public function get colorTransform() : ColorTransform
  188. {
  189. return _colorTransformMethod ? _colorTransformMethod.colorTransform : null;
  190. }
  191. public function set colorTransform(value : ColorTransform) : void
  192. {
  193. if (value) {
  194. colorTransformMethod ||= new ColorTransformMethod();
  195. _colorTransformMethod.colorTransform = value;
  196. }
  197. else if (!value) {
  198. if (_colorTransformMethod)
  199. colorTransformMethod = null;
  200. colorTransformMethod = _colorTransformMethod = null;
  201. }
  202. }
  203. /**
  204. * @inheritDoc
  205. */
  206. override public function dispose() : void
  207. {
  208. super.dispose();
  209. _normalMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  210. _normalMethod.dispose();
  211. _diffuseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  212. _diffuseMethod.dispose();
  213. if (_shadowMethod) {
  214. _diffuseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  215. _shadowMethod.dispose();
  216. }
  217. _ambientMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  218. _ambientMethod.dispose();
  219. if (_specularMethod) {
  220. _ambientMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  221. _specularMethod.dispose();
  222. }
  223. if (_colorTransformMethod) {
  224. _colorTransformMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  225. _colorTransformMethod.dispose();
  226. }
  227. for (var i : int = 0; i < _methods.length; ++i) {
  228. _methods[i].method.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  229. _methods[i].method.dispose();
  230. }
  231. _methods = null;
  232. }
  233. /**
  234. * Adds a method to change the material after all lighting is performed.
  235. * @param method The method to be added.
  236. */
  237. public function addMethod(method : EffectMethodBase) : void
  238. {
  239. _methods.push(new MethodSet(method));
  240. method.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  241. invalidateShaderProgram();
  242. }
  243. public function hasMethod(method : EffectMethodBase) : Boolean
  244. {
  245. return getMethodSetForMethod(method) != null;
  246. }
  247. /**
  248. * Inserts a method to change the material after all lighting is performed at the given index.
  249. * @param method The method to be added.
  250. * @param index The index of the method's occurrence
  251. */
  252. public function addMethodAt(method : EffectMethodBase, index : int) : void
  253. {
  254. _methods.splice(index, 0, new MethodSet(method));
  255. method.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  256. invalidateShaderProgram();
  257. }
  258. public function getMethodAt(index : int) : EffectMethodBase
  259. {
  260. return EffectMethodBase(_methods[index].method);
  261. }
  262. public function get numMethods() : int
  263. {
  264. return _methods.length;
  265. }
  266. /**
  267. * Removes a method from the pass.
  268. * @param method The method to be removed.
  269. */
  270. public function removeMethod(method : EffectMethodBase) : void
  271. {
  272. var methodSet : MethodSet = getMethodSetForMethod(method);
  273. if (methodSet != null) {
  274. var index : int = _methods.indexOf(methodSet);
  275. _methods.splice(index, 1);
  276. method.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  277. invalidateShaderProgram();
  278. }
  279. }
  280. /**
  281. * The tangent space normal map to influence the direction of the surface for each texel.
  282. */
  283. public function get normalMap() : Texture2DBase
  284. {
  285. return _normalMethod.normalMap;
  286. }
  287. public function set normalMap(value : Texture2DBase) : void
  288. {
  289. _normalMethod.normalMap = value;
  290. }
  291. /**
  292. * @inheritDoc
  293. */
  294. public function get normalMethod() : BasicNormalMethod
  295. {
  296. return _normalMethod;
  297. }
  298. public function set normalMethod(value : BasicNormalMethod) : void
  299. {
  300. _normalMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  301. value.copyFrom(_normalMethod);
  302. _normalMethod = value;
  303. _normalMethodVO = _normalMethod.createMethodVO();
  304. _normalMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  305. invalidateShaderProgram();
  306. }
  307. public function get ambientMethod() : BasicAmbientMethod
  308. {
  309. return _ambientMethod;
  310. }
  311. public function set ambientMethod(value : BasicAmbientMethod) : void
  312. {
  313. _ambientMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  314. value.copyFrom(_ambientMethod);
  315. _ambientMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  316. _ambientMethod = value;
  317. _ambientMethodVO = _ambientMethod.createMethodVO();
  318. invalidateShaderProgram();
  319. }
  320. public function get shadowMethod() : ShadowMapMethodBase
  321. {
  322. return _shadowMethod;
  323. }
  324. public function set shadowMethod(value : ShadowMapMethodBase) : void
  325. {
  326. if (_shadowMethod) _shadowMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  327. _shadowMethod = value;
  328. if (_shadowMethod) {
  329. _shadowMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  330. _shadowMethodVO = _shadowMethod.createMethodVO();
  331. }
  332. else
  333. _shadowMethodVO = null;
  334. invalidateShaderProgram();
  335. }
  336. /**
  337. * The method to perform diffuse shading.
  338. */
  339. public function get diffuseMethod() : BasicDiffuseMethod
  340. {
  341. return _diffuseMethod;
  342. }
  343. public function set diffuseMethod(value : BasicDiffuseMethod) : void
  344. {
  345. _diffuseMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  346. value.copyFrom(_diffuseMethod);
  347. _diffuseMethod = value;
  348. _diffuseMethodVO = _diffuseMethod.createMethodVO();
  349. _diffuseMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  350. invalidateShaderProgram();
  351. }
  352. /**
  353. * The method to perform specular shading.
  354. */
  355. public function get specularMethod() : BasicSpecularMethod
  356. {
  357. return _specularMethod;
  358. }
  359. public function set specularMethod(value : BasicSpecularMethod) : void
  360. {
  361. if (_specularMethod) {
  362. _specularMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  363. if (value) value.copyFrom(_specularMethod);
  364. }
  365. _specularMethod = value;
  366. if (_specularMethod) {
  367. _specularMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  368. _specularMethodVO = _specularMethod.createMethodVO();
  369. }
  370. else _specularMethodVO = null;
  371. invalidateShaderProgram();
  372. }
  373. /**
  374. * @private
  375. */
  376. arcane function get colorTransformMethod() : ColorTransformMethod
  377. {
  378. return _colorTransformMethod;
  379. }
  380. arcane function set colorTransformMethod(value : ColorTransformMethod) : void
  381. {
  382. if (_colorTransformMethod == value) return;
  383. if (_colorTransformMethod) _colorTransformMethod.removeEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  384. if (!_colorTransformMethod || !value) invalidateShaderProgram();
  385. _colorTransformMethod = value;
  386. if (_colorTransformMethod) {
  387. _colorTransformMethod.addEventListener(ShadingMethodEvent.SHADER_INVALIDATED, onShaderInvalidated);
  388. _colorTransformMethodVO = _colorTransformMethod.createMethodVO();
  389. }
  390. else _colorTransformMethodVO = null;
  391. }
  392. arcane override function set numPointLights(value : uint) : void
  393. {
  394. super.numPointLights = value;
  395. invalidateShaderProgram();
  396. }
  397. arcane override function set numDirectionalLights(value : uint) : void
  398. {
  399. super.numDirectionalLights = value;
  400. invalidateShaderProgram();
  401. }
  402. arcane override function set numLightProbes(value : uint) : void
  403. {
  404. super.numLightProbes = value;
  405. invalidateShaderProgram();
  406. }
  407. /**
  408. * @inheritDoc
  409. */
  410. arcane override function getVertexCode(animatorCode : String) : String
  411. {
  412. var normal : String = _animationTargetRegisters.length > 1? _animationTargetRegisters[1] : null;
  413. var projectionVertexCode : String = getProjectionCode(_animationTargetRegisters[0], _projectedTargetRegister, normal);
  414. _vertexCode = animatorCode + projectionVertexCode + _vertexCode;
  415. return _vertexCode;
  416. }
  417. private function getProjectionCode(positionRegister : String, projectionRegister : String, normalRegister : String) : String
  418. {
  419. var code : String = "";
  420. var pos : String = positionRegister;
  421. // if we need projection somewhere
  422. if (projectionRegister) {
  423. code += "m44 "+projectionRegister+", " + pos + ", vc0 \n" +
  424. "mov vt7, " + projectionRegister + "\n" +
  425. "mul op, vt7, vc4\n";
  426. }
  427. else {
  428. code += "m44 vt7, "+pos+", vc0 \n" +
  429. "mul op, vt7, vc4\n"; // 4x4 matrix transform from stream 0 to output clipspace
  430. }
  431. return code;
  432. }
  433. /**
  434. * @inheritDoc
  435. */
  436. arcane override function getFragmentCode() : String
  437. {
  438. return _fragmentCode;
  439. }
  440. /**
  441. * @inheritDoc
  442. */
  443. override arcane function activate(stage3DProxy : Stage3DProxy, camera : Camera3D, textureRatioX : Number, textureRatioY : Number) : void
  444. {
  445. var context : Context3D = stage3DProxy._context3D;
  446. var len : uint = _methods.length;
  447. super.activate(stage3DProxy, camera, textureRatioX, textureRatioY);
  448. if (_normalDependencies > 0 && _normalMethod.hasOutput) _normalMethod.activate(_normalMethodVO, stage3DProxy);
  449. _ambientMethod.activate(_ambientMethodVO, stage3DProxy);
  450. if (_shadowMethod) _shadowMethod.activate(_shadowMethodVO, stage3DProxy);
  451. _diffuseMethod.activate(_diffuseMethodVO, stage3DProxy);
  452. if (_usingSpecularMethod) _specularMethod.activate(_specularMethodVO, stage3DProxy);
  453. if (_colorTransformMethod) _colorTransformMethod.activate(_colorTransformMethodVO, stage3DProxy);
  454. for (var i : int = 0; i < len; ++i) {
  455. var set : MethodSet = _methods[i];
  456. set.method.activate(set.data, stage3DProxy);
  457. }
  458. if (_cameraPositionIndex >= 0) {
  459. var pos : Vector3D = camera.scenePosition;
  460. _vertexConstantData[_cameraPositionIndex] = pos.x;
  461. _vertexConstantData[_cameraPositionIndex + 1] = pos.y;
  462. _vertexConstantData[_cameraPositionIndex + 2] = pos.z;
  463. }
  464. }
  465. /**
  466. * @inheritDoc
  467. */
  468. arcane override function deactivate(stage3DProxy : Stage3DProxy) : void
  469. {
  470. super.deactivate(stage3DProxy);
  471. var len : uint = _methods.length;
  472. if (_normalDependencies > 0 && _normalMethod.hasOutput) _normalMethod.deactivate(_normalMethodVO, stage3DProxy);
  473. _ambientMethod.deactivate(_ambientMethodVO, stage3DProxy);
  474. if (_shadowMethod) _shadowMethod.deactivate(_shadowMethodVO, stage3DProxy);
  475. _diffuseMethod.deactivate(_diffuseMethodVO, stage3DProxy);
  476. if (_usingSpecularMethod) _specularMethod.deactivate(_specularMethodVO, stage3DProxy);
  477. if (_colorTransformMethod) _colorTransformMethod.deactivate(_colorTransformMethodVO, stage3DProxy);
  478. var set : MethodSet;
  479. for (var i : uint = 0; i < len; ++i) {
  480. set = _methods[i];
  481. set.method.deactivate(set.data, stage3DProxy);
  482. }
  483. }
  484. /**
  485. * @inheritDoc
  486. */
  487. arcane override function render(renderable : IRenderable, stage3DProxy : Stage3DProxy, camera : Camera3D, lightPicker : LightPickerBase) : void
  488. {
  489. var i : uint;
  490. var context : Context3D = stage3DProxy._context3D;
  491. if (_uvBufferIndex >= 0) stage3DProxy.setSimpleVertexBuffer(_uvBufferIndex, renderable.getUVBuffer(stage3DProxy), Context3DVertexBufferFormat.FLOAT_2, renderable.UVBufferOffset);
  492. if (_secondaryUVBufferIndex >= 0) stage3DProxy.setSimpleVertexBuffer(_secondaryUVBufferIndex, renderable.getSecondaryUVBuffer(stage3DProxy), Context3DVertexBufferFormat.FLOAT_2, renderable.secondaryUVBufferOffset);
  493. if (_normalBufferIndex >= 0) stage3DProxy.setSimpleVertexBuffer(_normalBufferIndex, renderable.getVertexNormalBuffer(stage3DProxy), Context3DVertexBufferFormat.FLOAT_3, renderable.normalBufferOffset);
  494. if (_tangentBufferIndex >= 0) stage3DProxy.setSimpleVertexBuffer(_tangentBufferIndex, renderable.getVertexTangentBuffer(stage3DProxy), Context3DVertexBufferFormat.FLOAT_3, renderable.tangentBufferOffset);
  495. var uvTransform : Matrix;
  496. if (_animateUVs) {
  497. uvTransform = renderable.uvTransform;
  498. if (uvTransform) {
  499. _vertexConstantData[_uvTransformIndex] = uvTransform.a;
  500. _vertexConstantData[_uvTransformIndex+1] = uvTransform.b;
  501. _vertexConstantData[_uvTransformIndex+3] = uvTransform.tx;
  502. _vertexConstantData[_uvTransformIndex+4] = uvTransform.c;
  503. _vertexConstantData[_uvTransformIndex+5] = uvTransform.d;
  504. _vertexConstantData[_uvTransformIndex+7] = uvTransform.ty;
  505. }
  506. else {
  507. trace("Warning: animateUVs is set to true with an IRenderable without a uvTransform. Identity matrix assumed.");
  508. _vertexConstantData[_uvTransformIndex] = 1;
  509. _vertexConstantData[_uvTransformIndex+1] = 0;
  510. _vertexConstantData[_uvTransformIndex+3] = 0;
  511. _vertexConstantData[_uvTransformIndex+4] = 0;
  512. _vertexConstantData[_uvTransformIndex+5] = 1;
  513. _vertexConstantData[_uvTransformIndex+7] = 0;
  514. }
  515. }
  516. if (_numLights > 0 && (_combinedLightSources & LightSources.LIGHTS))
  517. updateLights(lightPicker.directionalLights, lightPicker.pointLights, stage3DProxy);
  518. if (_numLightProbes > 0 && (_combinedLightSources & LightSources.PROBES))
  519. updateProbes(lightPicker.lightProbes, lightPicker.lightProbeWeights, stage3DProxy);
  520. if (_sceneMatrixIndex >= 0)
  521. renderable.sceneTransform.copyRawDataTo(_vertexConstantData, _sceneMatrixIndex, true);
  522. if (_sceneNormalMatrixIndex >= 0)
  523. renderable.inverseSceneTransform.copyRawDataTo(_vertexConstantData, _sceneNormalMatrixIndex, false);
  524. if (_normalDependencies > 0 && _normalMethod.hasOutput)
  525. _normalMethod.setRenderState(_normalMethodVO, renderable, stage3DProxy, camera);
  526. _ambientMethod.setRenderState(_ambientMethodVO, renderable, stage3DProxy, camera);
  527. _ambientMethod._lightAmbientR = _ambientLightR;
  528. _ambientMethod._lightAmbientG = _ambientLightG;
  529. _ambientMethod._lightAmbientB = _ambientLightB;
  530. if (_shadowMethod) _shadowMethod.setRenderState(_shadowMethodVO, renderable, stage3DProxy, camera);
  531. _diffuseMethod.setRenderState(_diffuseMethodVO, renderable, stage3DProxy, camera);
  532. if (_usingSpecularMethod) _specularMethod.setRenderState(_specularMethodVO, renderable, stage3DProxy, camera);
  533. if (_colorTransformMethod) _colorTransformMethod.setRenderState(_colorTransformMethodVO, renderable, stage3DProxy, camera);
  534. var len : uint = _methods.length;
  535. for (i = 0; i < len; ++i) {
  536. var set : MethodSet = _methods[i];
  537. set.method.setRenderState(set.data, renderable, stage3DProxy, camera);
  538. }
  539. context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, _vertexConstantIndex, _vertexConstantData, _numUsedVertexConstants-_vertexConstantIndex);
  540. context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _fragmentConstantData, _numUsedFragmentConstants);
  541. super.render(renderable, stage3DProxy, camera, lightPicker);
  542. }
  543. /**
  544. * Marks the shader program as invalid, so it will be recompiled before the next render.
  545. */
  546. arcane override function invalidateShaderProgram(updateMaterial : Boolean = true) : void
  547. {
  548. super.invalidateShaderProgram(updateMaterial);
  549. _passesDirty = true;
  550. _passes = new Vector.<MaterialPassBase>();
  551. if (_normalMethod.hasOutput) addPasses(_normalMethod.passes);
  552. addPasses(_ambientMethod.passes);
  553. if (_shadowMethod) addPasses(_shadowMethod.passes);
  554. addPasses(_diffuseMethod.passes);
  555. if (_specularMethod) addPasses(_specularMethod.passes);
  556. if (_colorTransformMethod) addPasses(_colorTransformMethod.passes);
  557. for (var i : uint = 0; i < _methods.length; ++i) {
  558. addPasses(_methods[i].method.passes);
  559. }
  560. }
  561. /**
  562. * @inheritDoc
  563. */
  564. override arcane function updateProgram(stage3DProxy : Stage3DProxy) : void
  565. {
  566. reset();
  567. super.updateProgram(stage3DProxy);
  568. }
  569. /**
  570. * Resets the compilation state.
  571. */
  572. private function reset() : void
  573. {
  574. _numLights = _numPointLights + _numDirectionalLights;
  575. _numProbeRegisters = Math.ceil(_numLightProbes/4);
  576. if (_specularMethod)
  577. _combinedLightSources = _specularLightSources | _diffuseLightSources;
  578. else
  579. _combinedLightSources = _diffuseLightSources;
  580. _usingSpecularMethod = _specularMethod && (
  581. (_numLights > 0 && (_specularLightSources & LightSources.LIGHTS)) ||
  582. (_numLightProbes > 0 && (_specularLightSources & LightSources.PROBES)));
  583. _uvTransformIndex = -1;
  584. _cameraPositionIndex = -1;
  585. _commonsDataIndex = -1;
  586. _uvBufferIndex = -1;
  587. _secondaryUVBufferIndex = -1;
  588. _normalBufferIndex = -1;
  589. _tangentBufferIndex = -1;
  590. _lightDataIndex = -1;
  591. _sceneMatrixIndex = -1;
  592. _sceneNormalMatrixIndex = -1;
  593. _probeWeightsIndex = -1;
  594. _pointLightRegisters = new Vector.<ShaderRegisterElement>(_numPointLights*3, true);
  595. _dirLightRegisters = new Vector.<ShaderRegisterElement>(_numDirectionalLights*3, true);
  596. _lightDataLength = _numLights*3;
  597. _registerCache = new ShaderRegisterCache();
  598. _vertexConstantIndex = _registerCache.vertexConstantOffset = 5;
  599. _registerCache.vertexAttributesOffset = 1;
  600. _registerCache.reset();
  601. _lightInputIndices = new Vector.<uint>(_numLights, true);
  602. _commonsReg = null;
  603. _numUsedVertexConstants = 0;
  604. _numUsedStreams = 1;
  605. _animatableAttributes = ["va0"];
  606. _animationTargetRegisters = ["vt0"];
  607. _vertexCode = "";
  608. _fragmentCode = "";
  609. _projectedTargetRegister = null;
  610. _localPositionRegister = _registerCache.getFreeVertexVectorTemp();
  611. _registerCache.addVertexTempUsages(_localPositionRegister, 1);
  612. compile();
  613. _numUsedVertexConstants = _registerCache.numUsedVertexConstants;
  614. _numUsedFragmentConstants = _registerCache.numUsedFragmentConstants;
  615. _numUsedStreams = _registerCache.numUsedStreams;
  616. _numUsedTextures = _registerCache.numUsedTextures;
  617. _vertexConstantData.length = (_numUsedVertexConstants-_vertexConstantIndex)*4;
  618. _fragmentConstantData.length = _numUsedFragmentConstants*4;
  619. initCommonsData();
  620. if (_uvTransformIndex >= 0)
  621. initUVTransformData();
  622. if (_cameraPositionIndex >= 0)
  623. _vertexConstantData[_cameraPositionIndex + 3] = 1;
  624. updateMethodConstants();
  625. cleanUp();
  626. }
  627. private function updateMethodConstants() : void
  628. {
  629. if (_normalMethod) _normalMethod.initConstants(_normalMethodVO);
  630. if (_diffuseMethod) _diffuseMethod.initConstants(_diffuseMethodVO);
  631. if (_ambientMethod) _ambientMethod.initConstants(_ambientMethodVO);
  632. if (_specularMethod) _specularMethod.initConstants(_specularMethodVO);
  633. if (_shadowMethod) _shadowMethod.initConstants(_shadowMethodVO);
  634. if (_colorTransformMethod) _colorTransformMethod.initConstants(_colorTransformMethodVO);
  635. var len : uint = _methods.length;
  636. for (var i : uint = 0; i < len; ++i) {
  637. _methods[i].method.initConstants(_methods[i].data);
  638. }
  639. }
  640. private function initUVTransformData() : void
  641. {
  642. _vertexConstantData[_uvTransformIndex] = 1;
  643. _vertexConstantData[_uvTransformIndex+1] = 0;
  644. _vertexConstantData[_uvTransformIndex+2] = 0;
  645. _vertexConstantData[_uvTransformIndex+3] = 0;
  646. _vertexConstantData[_uvTransformIndex+4] = 0;
  647. _vertexConstantData[_uvTransformIndex+5] = 1;
  648. _vertexConstantData[_uvTransformIndex+6] = 0;
  649. _vertexConstantData[_uvTransformIndex+7] = 0;
  650. }
  651. private function initCommonsData() : void
  652. {
  653. _fragmentConstantData[_commonsDataIndex] = .5;
  654. _fragmentConstantData[_commonsDataIndex + 1] = 0;
  655. _fragmentConstantData[_commonsDataIndex + 2] = 1/255;
  656. _fragmentConstantData[_commonsDataIndex + 3] = 1;
  657. }
  658. private function cleanUp() : void
  659. {
  660. nullifyCompilationData();
  661. cleanUpMethods();
  662. }
  663. private function nullifyCompilationData() : void
  664. {
  665. _pointLightRegisters = null;
  666. _dirLightRegisters = null;
  667. _projectionFragmentReg = null;
  668. _viewDirFragmentReg = null;
  669. _normalVarying = null;
  670. _tangentVarying = null;
  671. _bitangentVarying = null;
  672. _uvVaryingReg = null;
  673. _secondaryUVVaryingReg = null;
  674. _viewDirVaryingReg = null;
  675. _shadedTargetReg = null;
  676. _globalPositionVertexReg = null;
  677. _globalPositionVaryingReg = null;
  678. _localPositionRegister = null;
  679. _positionMatrixRegs = null;
  680. _normalInput = null;
  681. _tangentInput = null;
  682. _animatedNormalReg = null;
  683. _animatedTangentReg = null;
  684. _commonsReg = null;
  685. _registerCache.dispose();
  686. _registerCache = null;
  687. }
  688. private function cleanUpMethods() : void
  689. {
  690. if (_normalMethod) _normalMethod.cleanCompilationData();
  691. if (_diffuseMethod) _diffuseMethod.cleanCompilationData();
  692. if (_ambientMethod) _ambientMethod.cleanCompilationData();
  693. if (_specularMethod) _specularMethod.cleanCompilationData();
  694. if (_shadowMethod) _shadowMethod.cleanCompilationData();
  695. if (_colorTransformMethod) _colorTransformMethod.cleanCompilationData();
  696. var len : uint = _methods.length;
  697. for (var i : uint = 0; i < len; ++i) {
  698. _methods[i].method.cleanCompilationData();
  699. }
  700. }
  701. /**
  702. * Compiles the actual shader code.
  703. */
  704. private function compile() : void
  705. {
  706. createCommons();
  707. calculateDependencies();
  708. if (_projectionDependencies > 0) compileProjCode();
  709. if (_uvDependencies > 0) compileUVCode();
  710. if (_secondaryUVDependencies > 0) compileSecondaryUVCode();
  711. if (_globalPosDependencies > 0) compileGlobalPositionCode();
  712. updateMethodRegisters(_normalMethod);
  713. if (_normalDependencies > 0) {
  714. // needs to be created before view
  715. _animatedNormalReg = _registerCache.getFreeVertexVectorTemp();
  716. _registerCache.addVertexTempUsages(_animatedNormalReg, 1);
  717. if (_normalDependencies > 0) compileNormalCode();
  718. }
  719. if (_viewDirDependencies > 0) compileViewDirCode();
  720. updateMethodRegisters(_diffuseMethod);
  721. if (_shadowMethod) updateMethodRegisters(_shadowMethod);
  722. updateMethodRegisters(_ambientMethod);
  723. if (_specularMethod) updateMethodRegisters(_specularMethod);
  724. if (_colorTransformMethod) updateMethodRegisters(_colorTransformMethod);
  725. for (var i : uint = 0; i < _methods.length; ++i)
  726. updateMethodRegisters(_methods[i].method);
  727. _shadedTargetReg = _registerCache.getFreeFragmentVectorTemp();
  728. _registerCache.addFragmentTempUsages(_shadedTargetReg, 1);
  729. compileLightingCode();
  730. compileMethods();
  731. _fragmentCode += "mov " + _registerCache.fragmentOutputRegister + ", " + _shadedTargetReg + "\n";
  732. _registerCache.removeFragmentTempUsage(_shadedTargetReg);
  733. }
  734. private function compileProjCode() : void
  735. {
  736. _projectionFragmentReg = _registerCache.getFreeVarying();
  737. _projectedTargetRegister = _registerCache.getFreeVertexVectorTemp().toString();
  738. _vertexCode += "mov " + _projectionFragmentReg + ", " + _projectedTargetRegister + "\n";
  739. }
  740. private function updateMethodRegisters(method : ShadingMethodBase) : void
  741. {
  742. method.globalPosReg = _globalPositionVaryingReg;
  743. method.normalFragmentReg = _normalFragmentReg;
  744. method.projectionReg = _projectionFragmentReg;
  745. method.UVFragmentReg = _uvVaryingReg;
  746. method.tangentVaryingReg = _tangentVarying;
  747. method.secondaryUVFragmentReg = _secondaryUVVaryingReg;
  748. method.viewDirFragmentReg = _viewDirFragmentReg;
  749. method.viewDirVaryingReg = _viewDirVaryingReg;
  750. }
  751. /**
  752. * Adds passes to the list.
  753. */
  754. private function addPasses(passes : Vector.<MaterialPassBase>) : void
  755. {
  756. if (!passes) return;
  757. var len : uint = passes.length;
  758. for (var i : uint = 0; i < len; ++i) {
  759. passes[i].material = material;
  760. _passes.push(passes[i]);
  761. }
  762. }
  763. /**
  764. * Calculates register dependencies for commonly used data.
  765. */
  766. private function calculateDependencies() : void
  767. {
  768. var len : uint;
  769. _normalDependencies = 0;
  770. _viewDirDependencies = 0;
  771. _uvDependencies = 0;
  772. _secondaryUVDependencies = 0;
  773. _globalPosDependencies = 0;
  774. setupAndCountMethodDependencies(_diffuseMethod, _diffuseMethodVO);
  775. if (_shadowMethod) setupAndCountMethodDependencies(_shadowMethod, _shadowMethodVO);
  776. setupAndCountMethodDependencies(_ambientMethod, _ambientMethodVO);
  777. if (_usingSpecularMethod) setupAndCountMethodDependencies(_specularMethod, _specularMethodVO);
  778. if (_colorTransformMethod) setupAndCountMethodDependencies(_colorTransformMethod, _colorTransformMethodVO);
  779. len = _methods.length;
  780. for (var i : uint = 0; i < len; ++i)
  781. setupAndCountMethodDependencies(_methods[i].method, _methods[i].data);
  782. if (_normalDependencies > 0 && _normalMethod.hasOutput) setupAndCountMethodDependencies(_normalMethod, _normalMethodVO);
  783. if (_viewDirDependencies > 0) ++_globalPosDependencies;
  784. // todo: add spotlight check
  785. if (_numPointLights > 0 && (_combinedLightSources & LightSources.LIGHTS)) {
  786. ++_globalPosDependencies;
  787. _usesGlobalPosFragment = true;
  788. }
  789. }
  790. private function setupAndCountMethodDependencies(method : ShadingMethodBase, methodVO : MethodVO) : void
  791. {
  792. setupMethod(method, methodVO);
  793. countDependencies(methodVO);
  794. }
  795. private function countDependencies(methodVO : MethodVO) : void
  796. {
  797. if (methodVO.needsProjection) ++_projectionDependencies;
  798. if (methodVO.needsGlobalPos) {
  799. ++_globalPosDependencies;
  800. _usesGlobalPosFragment = true;
  801. }
  802. if (methodVO.needsNormals) ++_normalDependencies;
  803. if (methodVO.needsTangents) ++_tangentDependencies;
  804. if (methodVO.needsView) ++_viewDirDependencies;
  805. if (methodVO.needsUV) ++_uvDependencies;
  806. if (methodVO.needsSecondaryUV) ++_secondaryUVDependencies;
  807. }
  808. private function setupMethod(method : ShadingMethodBase, methodVO : MethodVO) : void
  809. {
  810. method.reset();
  811. methodVO.reset();
  812. methodVO.vertexData = _vertexConstantData;
  813. methodVO.fragmentData = _fragmentConstantData;
  814. methodVO.vertexConstantsOffset = _vertexConstantIndex;
  815. methodVO.useSmoothTextures = _smooth;
  816. methodVO.repeatTextures = _repeat;
  817. methodVO.useMipmapping = _mipmap;
  818. methodVO.numLights = _numLights + _numLightProbes;
  819. method.initVO(methodVO);
  820. }
  821. private function compileGlobalPositionCode() : void
  822. {
  823. _globalPositionVertexReg = _registerCache.getFreeVertexVectorTemp();
  824. _registerCache.addVertexTempUsages(_globalPositionVertexReg, _globalPosDependencies);
  825. _positionMatrixRegs = new Vector.<ShaderRegisterElement>();
  826. _positionMatrixRegs[0] = _registerCache.getFreeVertexConstant();
  827. _positionMatrixRegs[1] = _registerCache.getFreeVertexConstant();
  828. _positionMatrixRegs[2] = _registerCache.getFreeVertexConstant();
  829. _registerCache.getFreeVertexConstant();
  830. _sceneMatrixIndex = (_positionMatrixRegs[0].index - _vertexConstantIndex)*4;
  831. _vertexCode += "m44 " + _globalPositionVertexReg + ".xyz, " + _localPositionRegister.toString() + ", " + _positionMatrixRegs[0].toString() + "\n" +
  832. "mov " + _globalPositionVertexReg + ".w, " + _localPositionRegister + ".w \n";
  833. // _registerCache.removeVertexTempUsage(_localPositionRegister);
  834. // todo: add spotlight check as well
  835. if (_usesGlobalPosFragment) {
  836. _globalPositionVaryingReg = _registerCache.getFreeVarying();
  837. _vertexCode += "mov " + _globalPositionVaryingReg + ", " + _globalPositionVertexReg + "\n";
  838. // _registerCache.removeVertexTempUsage(_globalPositionVertexReg);
  839. }
  840. }
  841. private function compileUVCode() : void
  842. {
  843. var uvAttributeReg : ShaderRegisterElement = _registerCache.getFreeVertexAttribute();
  844. _uvVaryingReg = _registerCache.getFreeVarying();
  845. _uvBufferIndex = uvAttributeReg.index;
  846. if (_animateUVs) {
  847. // a, b, 0, tx
  848. // c, d, 0, ty
  849. var uvTransform1 : ShaderRegisterElement = _registerCache.getFreeVertexConstant();
  850. var uvTransform2 : ShaderRegisterElement = _registerCache.getFreeVertexConstant();
  851. _uvTransformIndex = (uvTransform1.index - _vertexConstantIndex)*4;
  852. _vertexCode += "dp4 " + _uvVaryingReg + ".x, " + uvAttributeReg + ", " + uvTransform1 + "\n" +
  853. "dp4 " + _uvVaryingReg + ".y, " + uvAttributeReg + ", " + uvTransform2 + "\n" +
  854. "mov " + _uvVaryingReg + ".zw, " + uvAttributeReg + ".zw \n";
  855. }
  856. else {
  857. _vertexCode += "mov " + _uvVaryingReg + ", " + uvAttributeReg + "\n";
  858. }
  859. }
  860. private function compileSecondaryUVCode() : void
  861. {
  862. var uvAttributeReg : ShaderRegisterElement = _registerCache.getFreeVertexAttribute();
  863. _secondaryUVVaryingReg = _registerCache.getFreeVarying();
  864. _secondaryUVBufferIndex = uvAttributeReg.index;
  865. _vertexCode += "mov " + _secondaryUVVaryingReg + ", " + uvAttributeReg + "\n";
  866. }
  867. private function compileNormalCode() : void
  868. {
  869. var normalMatrix : Vector.<ShaderRegisterElement> = new Vector.<ShaderRegisterElement>(3, true);
  870. _normalFragmentReg = _registerCache.getFreeFragmentVectorTemp();
  871. _registerCache.addFragmentTempUsages(_normalFragmentReg, _normalDependencies);
  872. if (_normalMethod.hasOutput && !_normalMethod.tangentSpace) {
  873. _vertexCode += _normalMethod.getVertexCode(_normalMethodVO, _registerCache);
  874. _fragmentCode += _normalMethod.getFragmentCode(_normalMethodVO, _registerCache, _normalFragmentReg);
  875. return;
  876. }
  877. _normalInput = _registerCache.getFreeVertexAttribute();
  878. _normalBufferIndex = _normalInput.index;
  879. _normalVarying = _registerCache.getFreeVarying();
  880. _animatableAttributes.push(_normalInput.toString());
  881. _animationTargetRegisters.push(_animatedNormalReg.toString());
  882. normalMatrix[0] = _registerCache.getFreeVertexConstant();
  883. normalMatrix[1] = _registerCache.getFreeVertexConstant();
  884. normalMatrix[2] = _registerCache.getFreeVertexConstant();
  885. _registerCache.getFreeVertexConstant();
  886. _sceneNormalMatrixIndex = (normalMatrix[0].index-_vertexConstantIndex)*4;
  887. if (_normalMethod.hasOutput) {
  888. // tangent stream required
  889. compileTangentVertexCode(normalMatrix);
  890. compileTangentNormalMapFragmentCode();
  891. }
  892. else {
  893. _vertexCode += "m33 " + _normalVarying + ".xyz, " + _animatedNormalReg + ".xyz, " + normalMatrix[0] + "\n" +
  894. "mov " + _normalVarying + ".w, " + _animatedNormalReg + ".w \n";
  895. _fragmentCode += "nrm " + _normalFragmentReg + ".xyz, " + _normalVarying + ".xyz \n" +
  896. "mov " + _normalFragmentReg + ".w, " + _normalVarying + ".w \n";
  897. if (_tangentDependencies > 0) {
  898. _tangentInput = _registerCache.getFreeVertexAttribute();
  899. _tangentBufferIndex = _tangentInput.index;
  900. _tangentVarying = _registerCache.getFreeVarying();
  901. _vertexCode += "mov " + _tangentVarying + ", " + _tangentInput + "\n";
  902. }
  903. }
  904. _registerCache.removeVertexTempUsage(_animatedNormalReg);
  905. }
  906. private function compileTangentVertexCode(matrix : Vector.<ShaderRegisterElement>) : void
  907. {
  908. var normalTemp : ShaderRegisterElement;
  909. var tanTemp : ShaderRegisterElement;
  910. var bitanTemp1 : ShaderRegisterElement;
  911. var bitanTemp2 : ShaderRegisterElement;
  912. _tangentVarying = _registerCache.getFreeVarying();
  913. _bitangentVarying = _registerCache.getFreeVarying();
  914. _tangentInput = _registerCache.getFreeVertexAttribute();
  915. _tangentBufferIndex = _tangentInput.index;
  916. _animatedTangentReg = _registerCache.getFreeVertexVectorTemp();
  917. _registerCache.addVertexTempUsages(_animatedTangentReg, 1);
  918. _animatableAttributes.push(_tangentInput.toString());
  919. _animationTargetRegisters.push(_animatedTangentReg.toString());
  920. normalTemp = _registerCache.getFreeVertexVectorTemp();
  921. _registerCache.addVertexTempUsages(normalTemp, 1);
  922. _vertexCode += "m33 " + normalTemp + ".xyz, " + _animatedNormalReg + ".xyz, " + matrix[0].toString() + "\n" +
  923. "nrm " + normalTemp + ".xyz, " + normalTemp + ".xyz \n";
  924. tanTemp = _registerCache.getFreeVertexVectorTemp();
  925. _registerCache.addVertexTempUsages(tanTemp, 1);
  926. _vertexCode += "m33 " + tanTemp + ".xyz, " + _animatedTangentReg + ".xyz, " + matrix[0].toString() + "\n" +
  927. "nrm " + tanTemp + ".xyz, " + tanTemp + ".xyz \n";
  928. bitanTemp1 = _registerCache.getFreeVertexVectorTemp();
  929. _registerCache.addVertexTempUsages(bitanTemp1, 1);
  930. bitanTemp2 = _registerCache.getFreeVertexVectorTemp();
  931. _vertexCode += "mul " + bitanTemp1 + ".xyz, " + normalTemp + ".yzx, " + tanTemp + ".zxy \n" +
  932. "mul " + bitanTemp2 + ".xyz, " + normalTemp + ".zxy, " + tanTemp + ".yzx \n" +
  933. "sub " + bitanTemp2 + ".xyz, " + bitanTemp1 + ".xyz, " + bitanTemp2 + ".xyz \n" +
  934. "mov " + _tangentVarying + ".x, " + tanTemp + ".x \n" +
  935. "mov " + _tangentVarying + ".y, " + bitanTemp2 + ".x \n" +
  936. "mov " + _tangentVarying + ".z, " + normalTemp + ".x \n" +
  937. "mov " + _tangentVarying + ".w, " + _normalInput + ".w \n" +
  938. "mov " + _bitangentVarying + ".x, " + tanTemp + ".y \n" +
  939. "mov " + _bitangentVarying + ".y, " + bitanTemp2 + ".y \n" +
  940. "mov " + _bitangentVarying + ".z, " + normalTemp + ".y \n" +
  941. "mov " + _bitangentVarying + ".w, " + _normalInput + ".w \n" +
  942. "mov " + _normalVarying + ".x, " + tanTemp + ".z \n" +
  943. "mov " + _normalVarying + ".y, " + bitanTemp2 + ".z \n" +
  944. "mov " + _normalVarying + ".z, " + normalTemp + ".z \n" +
  945. "mov " + _normalVarying + ".w, " + _normalInput + ".w \n";
  946. _registerCache.removeVertexTempUsage(normalTemp);
  947. _registerCache.removeVertexTempUsage(tanTemp);
  948. _registerCache.removeVertexTempUsage(bitanTemp1);
  949. _registerCache.removeVertexTempUsage(_animatedTangentReg);
  950. }
  951. private function compileTangentNormalMapFragmentCode() : void
  952. {
  953. var t : ShaderRegisterElement;
  954. var b : ShaderRegisterElement;
  955. var n : ShaderRegisterElement;
  956. t = _registerCache.getFreeFragmentVectorTemp();
  957. _registerCache.addFragmentTempUsages(t, 1);
  958. b = _registerCache.getFreeFragmentVectorTemp();
  959. _registerCache.addFragmentTempUsages(b, 1);
  960. n = _registerCache.getFreeFragmentVectorTemp();
  961. _registerCache.addFragmentTempUsages(n, 1);
  962. _fragmentCode += "nrm " + t + ".xyz, " + _tangentVarying + ".xyz \n" +
  963. "mov " + t + ".w, " + _tangentVarying + ".w \n" +
  964. "nrm " + b + ".xyz, " + _bitangentVarying + ".xyz \n" +
  965. "nrm " + n + ".xyz, " + _normalVarying + ".xyz \n";
  966. var temp : ShaderRegisterElement = _registerCache.getFreeFragmentVectorTemp();
  967. _registerCache.addFragmentTempUsages(temp, 1);
  968. _fragmentCode += _normalMethod.getFragmentCode(_normalMethodVO, _registerCache, temp) +
  969. "sub " + temp + ".xyz, " + temp + ".xyz, " + _commonsReg + ".xxx \n" +
  970. "nrm " + temp + ".xyz, " + temp + ".xyz \n" +
  971. "m33 " + _normalFragmentReg + ".xyz, " + temp + ".xyz, " + t + " \n" +
  972. "mov " + _normalFragmentReg + ".w, " + _normalVarying + ".w \n";
  973. _registerCache.removeFragmentTempUsage(temp);
  974. if (_normalMethodVO.needsView) _registerCache.removeFragmentTempUsage(_viewDirFragmentReg);
  975. if (_normalMethodVO.needsGlobalPos) _registerCache.removeVertexTempUsage(_globalPositionVertexReg);
  976. _registerCache.removeFragmentTempUsage(b);
  977. _registerCache.removeFragmentTempUsage(t);
  978. _registerCache.removeFragmentTempUsage(n);
  979. }
  980. private function createCommons() : void
  981. {
  982. _commonsReg = _registerCache.getFreeFragmentConstant();
  983. _commonsDataIndex = _commonsReg.index*4;
  984. }
  985. private function compileViewDirCode() : void
  986. {
  987. var cameraPositionReg : ShaderRegisterElement = _registerCache.getFreeVertexConstant();
  988. _viewDirVaryingReg = _registerCache.getFreeVarying();
  989. _viewDirFragmentReg = _registerCache.getFreeFragmentVectorTemp();
  990. _registerCache.addFragmentTempUsages(_viewDirFragmentReg, _viewDirDependencies);
  991. _cameraPositionIndex = (cameraPositionReg.index-_vertexConstantIndex)*4;
  992. _vertexCode += "sub " + _viewDirVaryingReg + ", " + cameraPositionReg + ", " + _globalPositionVertexReg + "\n";
  993. _fragmentCode += "nrm " + _viewDirFragmentReg + ".xyz, " + _viewDirVaryingReg + ".xyz \n" +
  994. "mov " + _viewDirFragmentReg + ".w, " + _viewDirVaryingReg + ".w \n";
  995. _registerCache.removeVertexTempUsage(_globalPositionVertexReg);
  996. }
  997. private function compileLightingCode() : void
  998. {
  999. var shadowReg : ShaderRegisterElement;
  1000. initLightRegisters();
  1001. _vertexCode += _diffuseMethod.getVertexCode(_diffuseMethodVO, _registerCache);
  1002. _fragmentCode += _diffuseMethod.getFragmentPreLightingCode(_diffuseMethodVO, _registerCache);
  1003. if (_usingSpecularMethod) {
  1004. _vertexCode += _specularMethod.getVertexCode(_specularMethodVO, _registerCache);
  1005. _fragmentCode += _specularMethod.getFragmentPreLightingCode(_specularMethodVO, _registerCache);
  1006. }
  1007. _diffuseLightIndex = 0;
  1008. _specularLightIndex = 0;
  1009. if (_numLights > 0 && (_combinedLightSources & LightSources.LIGHTS)) {
  1010. compileDirectionalLightCode();
  1011. compilePointLightCode();
  1012. }
  1013. if (_numLightProbes > 0 && (_combinedLightSources & LightSources.PROBES))
  1014. compileLightProbeCode();
  1015. _vertexCode += _ambientMethod.getVertexCode(_ambientMethodVO, _registerCache);
  1016. _fragmentCode += _ambientMethod.getFragmentCode(_ambientMethodVO, _registerCache, _shadedTargetReg);
  1017. if (_ambientMethodVO.needsNormals) _registerCache.removeFragmentTempUsage(_normalFragmentReg);
  1018. if (_ambientMethodVO.needsView) _registerCache.removeFragmentTempUsage(_viewDirFragmentReg);
  1019. if (_shadowMethod) {
  1020. _vertexCode += _shadowMethod.getVertexCode(_shadowMethodVO, _registerCache);
  1021. // using normal to contain shadow data if available is perhaps risky :s
  1022. // todo: improve compilation with lifetime analysis so this isn't necessary?
  1023. if (_normalDependencies == 0) {
  1024. shadowReg = _registerCache.getFreeFragmentVectorTemp();
  1025. _registerCache.addFragmentTempUsages(shadowReg, 1);
  1026. }
  1027. else
  1028. shadowReg = _normalFragmentReg;
  1029. _diffuseMethod.shadowRegister = shadowReg;
  1030. _fragmentCode += _shadowMethod.getFragmentCode(_shadowMethodVO, _registerCache, shadowReg);
  1031. }
  1032. _fragmentCode += _diffuseMethod.getFragmentPostLightingCode(_diffuseMethodVO, _registerCache, _shadedTargetReg);
  1033. if (_alphaPremultiplied) {
  1034. _fragmentCode += "add " + _shadedTargetReg + ".w, " + _shadedTargetReg + ".w, " + _commonsReg + ".z\n" +
  1035. "div " + _shadedTargetReg + ".xyz, " + _shadedTargetReg + ".xyz, " + _shadedTargetReg + ".w\n" +
  1036. "sub " + _shadedTargetReg + ".w, " + _shadedTargetReg + ".w, " + _commonsReg + ".z\n"
  1037. "sat " + _shadedTargetReg + ".xyz, " + _shadedTargetReg + ".xyz\n";
  1038. }
  1039. // resolve other dependencies as well?
  1040. if (_diffuseMethodVO.needsNormals) _registerCache.removeFragmentTempUsage(_normalFragmentReg);
  1041. if (_diffuseMethodVO.needsView) _registerCache.removeFragmentTempUsage(_viewDirFragmentReg);
  1042. if (_usingSpecularMethod) {
  1043. _specularMethod.shadowRegister = shadowReg;
  1044. _fragmentCode += _specularMethod.getFragmentPostLightingCode(_specularMethodVO, _registerCache, _shadedTargetReg);
  1045. if (_specularMethodVO.needsNormals) _registerCache.removeFragmentTempUsage(_normalFragmentReg);
  1046. if (_specularMethodVO.needsView) _registerCache.removeFragmentTempUsage(_viewDirFragmentReg);
  1047. }
  1048. }
  1049. private function initLightRegisters() : void
  1050. {
  1051. // init these first so we're sure they're in sequence
  1052. var i : uint, len : uint;
  1053. len = _dirLightRegisters.length;
  1054. for (i = 0; i < len; ++i) {
  1055. _dirLightRegisters[i] = _registerCache.getFreeFragmentConstant();
  1056. if (_lightDataIndex == -1) _lightDataIndex = _dirLightRegisters[i].index*4;
  1057. }
  1058. len = _pointLightRegisters.length;
  1059. for (i = 0; i < len; ++i) {
  1060. _pointLightRegisters[i] = _registerCache.getFreeFragmentConstant();
  1061. if (_lightDataIndex == -1) _lightDataIndex = _pointLightRegisters[i].index*4;
  1062. }
  1063. }
  1064. private function compileDirectionalLightCode() : void
  1065. {
  1066. var diffuseColorReg : ShaderRegisterElement;
  1067. var specularColorReg : ShaderRegisterElement;
  1068. var lightDirReg : ShaderRegisterElement;
  1069. var regIndex : int;
  1070. var addSpec : Boolean = _usingSpecularMethod && ((_specularLightSources & LightSources.LIGHTS) != 0);
  1071. var addDiff : Boolean = (_diffuseLightSources & LightSources.LIGHTS) != 0;
  1072. if (!(addSpec || addDiff)) return;
  1073. for (var i : uint = 0; i < _numDirectionalLights; ++i) {
  1074. lightDirReg = _dirLightRegisters[regIndex++];
  1075. diffuseColorReg = _dirLightRegisters[regIndex++];
  1076. specularColorReg = _dirLightRegisters[regIndex++];
  1077. if (addDiff) {
  1078. _fragmentCode += _diffuseMethod.getFragmentCodePerLight(_diffuseMethodVO, _diffuseLightIndex, lightDirReg, diffuseColorReg, _registerCache);
  1079. ++_diffuseLightIndex;
  1080. }
  1081. if (addSpec) {
  1082. _fragmentCode += _specularMethod.getFragmentCodePerLight(_specularMethodVO, _specularLightIndex, lightDirReg, specularColorReg, _registerCache);
  1083. ++_specularLightIndex;
  1084. }
  1085. }
  1086. }
  1087. private function compilePointLightCode() : void
  1088. {
  1089. var diffuseColorReg : ShaderRegisterElement;
  1090. var specularColorReg : ShaderRegisterElement;
  1091. var lightPosReg : ShaderRegisterElement;
  1092. var lightDirReg : ShaderRegisterElement;
  1093. var regIndex : int;
  1094. var addSpec : Boolean = _usingSpecularMethod && ((_specularLightSources & LightSources.LIGHTS) != 0);
  1095. var addDiff : Boolean = (_diffuseLightSources & LightSources.LIGHTS) != 0;
  1096. if (!(addSpec || addDiff)) return;
  1097. for (var i : uint = 0; i < _numPointLights; ++i) {
  1098. lightPosReg = _pointLightRegisters[regIndex++];
  1099. diffuseColorReg = _pointLightRegisters[regIndex++];
  1100. specularColorReg = _pointLightRegisters[regIndex++];
  1101. lightDirReg = _registerCache.getFreeFragmentVectorTemp();
  1102. _registerCache.addFragmentTempUsages(lightDirReg, 1);
  1103. // calculate direction
  1104. _fragmentCode += "sub " + lightDirReg + ", " + lightPosReg + ", " + _globalPositionVaryingReg + "\n" +
  1105. // attenuate
  1106. "dp3 " + lightDirReg + ".w, " + lightDirReg + ".xyz, " + lightDirReg + ".xyz\n" +
  1107. "sqt " + lightDirReg + ".w, " + lightDirReg + ".w\n" +
  1108. // w = d - radis
  1109. "sub " + lightDirReg + ".w, " + lightDirReg + ".w, " + diffuseColorReg + ".w\n" +
  1110. // w = (d - radius)/(max-min)
  1111. "mul " + lightDirReg + ".w, " + lightDirReg + ".w, " + specularColorReg + ".w\n" +
  1112. // w = clamp(w, 0, 1)
  1113. "sat " + lightDirReg + ".w, " + lightDirReg + ".w\n" +
  1114. // w = 1-w
  1115. "sub " + lightDirReg + ".w, " + lightPosReg + ".w, " + lightDirReg + ".w\n" +
  1116. // normalize
  1117. "nrm " + lightDirReg + ".xyz, " + lightDirReg + ".xyz \n";
  1118. if (_lightDataIndex == -1) _lightDataIndex = lightPosReg.index*4;
  1119. if (addDiff) {
  1120. // TODO: vo can contain register data
  1121. _fragmentCode += _diffuseMethod.getFragmentCodePerLight(_diffuseMethodVO, _diffuseLightIndex, lightDirReg, diffuseColorReg, _registerCache);
  1122. ++_diffuseLightIndex;
  1123. }
  1124. if (addSpec) {
  1125. _fragmentCode += _specularMethod.getFragmentCodePerLight(_specularMethodVO, _specularLightIndex, lightDirReg, specularColorReg, _registerCache);
  1126. ++_specularLightIndex;
  1127. }
  1128. _registerCache.removeFragmentTempUsage(lightDirReg);
  1129. }
  1130. }
  1131. private function compileLightProbeCode() : void
  1132. {
  1133. var weightReg : String;
  1134. var weightComponents : Array = [ ".x", ".y", ".z", ".w" ];
  1135. var weightRegisters : Vector.<ShaderRegisterElement> = new Vector.<ShaderRegisterElement>();
  1136. var i : uint;
  1137. var texReg : ShaderRegisterElement;
  1138. var addSpec : Boolean = _usingSpecularMethod && ((_specularLightSources & LightSources.PROBES) != 0);
  1139. var addDiff : Boolean = (_diffuseLightSources & LightSources.PROBES) != 0;
  1140. if (!(addSpec || addDiff)) return;
  1141. if (addDiff)
  1142. _lightProbeDiffuseIndices = new Vector.<uint>();
  1143. if (addSpec)
  1144. _lightProbeSpecularIndices = new Vector.<uint>();
  1145. for (i = 0; i < _numProbeRegisters; ++i) {
  1146. weightRegisters[i] = _registerCache.getFreeFragmentConstant();
  1147. if (i == 0) _probeWeightsIndex = weightRegisters[i].index*4;
  1148. }
  1149. for (i = 0; i < _numLightProbes; ++i) {
  1150. weightReg = weightRegisters[Math.floor(i/4)].toString() + weightComponents[i % 4];
  1151. if (addDiff) {
  1152. texReg = _registerCache.getFreeTextureReg();
  1153. _lightProbeDiffuseIndices[i] = texReg.index;
  1154. _fragmentCode += _diffuseMethod.getFragmentCodePerProbe(_diffuseMethodVO, _diffuseLightIndex, texReg, weightReg, _registerCache);
  1155. ++_diffuseLightIndex;
  1156. }
  1157. if (addSpec) {
  1158. texReg = _registerCache.getFreeTextureReg();
  1159. _lightProbeSpecularIndices[i] = texReg.index;
  1160. _fragmentCode += _specularMethod.getFragmentCodePerProbe(_specularMethodVO, _specularLightIndex, texReg, weightReg, _registerCache);
  1161. ++_specularLightIndex;
  1162. }
  1163. }
  1164. }
  1165. private function compileMethods() : void
  1166. {
  1167. var numMethods : uint = _methods.length;
  1168. var method : EffectMethodBase;
  1169. var data : MethodVO;
  1170. for (var i : uint = 0; i < numMethods; ++i) {
  1171. method = _methods[i].method;
  1172. data = _methods[i].data;
  1173. _vertexCode += method.getVertexCode(data, _registerCache);
  1174. if (data.needsGlobalPos) _registerCache.removeVertexTempUsage(_globalPositionVertexReg);
  1175. _fragmentCode += method.getFragmentCode(data, _registerCache, _shadedTargetReg);
  1176. if (data.needsNormals) _registerCache.removeFragmentTempUsage(_normalFragmentReg);
  1177. if (data.needsView) _registerCache.removeFragmentTempUsage(_viewDirFragmentReg);
  1178. }
  1179. if (_colorTransformMethod) {
  1180. _vertexCode += _colorTransformMethod.getVertexCode(_colorTransformMethodVO, _registerCache);
  1181. _fragmentCode += _colorTransformMethod.getFragmentCode(_colorTransformMethodVO, _registerCache, _shadedTargetReg);
  1182. }
  1183. }
  1184. /**
  1185. * Updates the lights data for the render state.
  1186. * @param lights The lights selected to shade the current object.
  1187. * @param numLights The amount of lights available.
  1188. * @param maxLights The maximum amount of lights supported.
  1189. */
  1190. private function updateLights(directionalLights : Vector.<DirectionalLight>, pointLights : Vector.<PointLight>, stage3DProxy : Stage3DProxy) : void
  1191. {
  1192. // first dirs, then points
  1193. var dirLight : DirectionalLight;
  1194. var pointLight : PointLight;
  1195. var i : uint, k : uint;
  1196. var len : int;
  1197. var dirPos : Vector3D;
  1198. _ambientLightR = _ambientLightG = _ambientLightB = 0;
  1199. len = directionalLights.length;
  1200. k = _lightDataIndex;
  1201. for (i = 0; i < len; ++i) {
  1202. dirLight = directionalLights[i];
  1203. dirPos = dirLight.sceneDirection;
  1204. _ambientLightR += dirLight._ambientR;
  1205. _ambientLightG += dirLight._ambientG;
  1206. _ambientLightB += dirLight._ambientB;
  1207. _fragmentConstantData[k++] = -dirPos.x;
  1208. _fragmentConstantData[k++] = -dirPos.y;
  1209. _fragmentConstantData[k++] = -dirPos.z;
  1210. _fragmentConstantData[k++] = 1;
  1211. _fragmentConstantData[k++] = dirLight._diffuseR;
  1212. _fragmentConstantData[k++] = dirLight._diffuseG;
  1213. _fragmentConstantData[k++] = dirLight._diffuseB;
  1214. _fragmentConstantData[k++] = 1;
  1215. _fragmentConstantData[k++] = dirLight._specularR;
  1216. _fragmentConstantData[k++] = dirLight._specularG;
  1217. _fragmentConstantData[k++] = dirLight._specularB;
  1218. _fragmentConstantData[k++] = 1;
  1219. }
  1220. // more directional supported than currently picked, need to clamp all to 0
  1221. if (_numDirectionalLights > len) {
  1222. i = k + (_numDirectionalLights - len) * 12;
  1223. while (k < i)
  1224. _fragmentConstantData[k++] = 0;
  1225. }
  1226. len = pointLights.length;
  1227. for (i = 0; i < len; ++i) {
  1228. pointLight = pointLights[i];
  1229. dirPos = pointLight.scenePosition;
  1230. _ambientLightR += pointLight._ambientR;
  1231. _ambientLightG += pointLight._ambientG;
  1232. _ambientLightB += pointLight._ambientB;
  1233. _fragmentConstantData[k++] = dirPos.x;
  1234. _fragmentConstantData[k++] = dirPos.y;
  1235. _fragmentConstantData[k++] = dirPos.z;
  1236. _fragmentConstantData[k++] = 1;
  1237. _fragmentConstantData[k++] = pointLight._diffuseR;
  1238. _fragmentConstantData[k++] = pointLight._diffuseG;
  1239. _fragmentConstantData[k++] = pointLight._diffuseB;
  1240. _fragmentConstantData[k++] = pointLight._radius;
  1241. _fragmentConstantData[k++] = pointLight._specularR;
  1242. _fragmentConstantData[k++] = pointLight._specularG;
  1243. _fragmentConstantData[k++] = pointLight._specularB;
  1244. _fragmentConstantData[k++] = pointLight._fallOffFactor;
  1245. }
  1246. // more directional supported than currently picked, need to clamp all to 0
  1247. if (_numPointLights > len) {
  1248. i = k + (len - _numPointLights) * 12;
  1249. for (; k < i; ++k)
  1250. _fragmentConstantData[k] = 0;
  1251. }
  1252. }
  1253. private function updateProbes(lightProbes : Vector.<LightProbe>, weights : Vector.<Number>, stage3DProxy : Stage3DProxy) : void
  1254. {
  1255. var probe : LightProbe;
  1256. var len : int = lightProbes.length;
  1257. var addDiff : Boolean = _diffuseMethod && ((_diffuseLightSources & LightSources.PROBES) != 0);
  1258. var addSpec : Boolean = _specularMethod && ((_specularLightSources & LightSources.PROBES) != 0);
  1259. if (!(addDiff || addSpec)) return;
  1260. for (var i : uint = 0; i < len; ++i) {
  1261. probe = lightProbes[i];
  1262. if (addDiff)
  1263. stage3DProxy.setTextureAt(_lightProbeDiffuseIndices[i], probe.diffuseMap.getTextureForStage3D(stage3DProxy));
  1264. if (addSpec)
  1265. stage3DProxy.setTextureAt(_lightProbeSpecularIndices[i], probe.specularMap.getTextureForStage3D(stage3DProxy));
  1266. }
  1267. _fragmentConstantData[_probeWeightsIndex] = weights[0];
  1268. _fragmentConstantData[_probeWeightsIndex + 1] = weights[1];
  1269. _fragmentConstantData[_probeWeightsIndex + 2] = weights[2];
  1270. _fragmentConstantData[_probeWeightsIndex + 3] = weights[3];
  1271. }
  1272. private function getMethodSetForMethod(method : EffectMethodBase) : MethodSet
  1273. {
  1274. var len : int = _methods.length;
  1275. for (var i : int = 0; i < len; ++i)
  1276. if (_methods[i].method == method) return _methods[i];
  1277. return null;
  1278. }
  1279. private function onShaderInvalidated(event : ShadingMethodEvent) : void
  1280. {
  1281. invalidateShaderProgram();
  1282. }
  1283. }
  1284. }
  1285. import away3d.arcane;
  1286. import away3d.materials.methods.EffectMethodBase;
  1287. import away3d.materials.methods.MethodVO;
  1288. class MethodSet
  1289. {
  1290. use namespace arcane;
  1291. public var method : EffectMethodBase;
  1292. public var data : MethodVO;
  1293. public function MethodSet(method : EffectMethodBase)
  1294. {
  1295. this.method = method;
  1296. data = method.createMethodVO();
  1297. }
  1298. }