/src/away3d/materials/methods/CelDiffuseMethod.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 134 lines · 81 code · 16 blank · 37 comment · 0 complexity · 5b4e00545e626df0b69a90b69f5635b5 MD5 · raw file

  1. package 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.ShaderRegisterData;
  7. import away3d.materials.compilation.ShaderRegisterElement;
  8. use namespace arcane;
  9. /**
  10. * CelDiffuseMethod provides a shading method to add diffuse cel (cartoon) shading.
  11. */
  12. public class CelDiffuseMethod extends CompositeDiffuseMethod
  13. {
  14. private var _levels:uint;
  15. private var _dataReg:ShaderRegisterElement;
  16. private var _smoothness:Number = .1;
  17. /**
  18. * Creates a new CelDiffuseMethod object.
  19. * @param levels The amount of shadow gradations.
  20. * @param baseDiffuseMethod An optional diffuse method on which the cartoon shading is based. If omitted, BasicDiffuseMethod is used.
  21. */
  22. public function CelDiffuseMethod(levels:uint = 3, baseDiffuseMethod:BasicDiffuseMethod = null)
  23. {
  24. super(clampDiffuse, baseDiffuseMethod);
  25. _levels = levels;
  26. }
  27. /**
  28. * @inheritDoc
  29. */
  30. override arcane function initConstants(vo:MethodVO):void
  31. {
  32. var data:Vector.<Number> = vo.fragmentData;
  33. var index:int = vo.secondaryFragmentConstantsIndex;
  34. super.initConstants(vo);
  35. data[index + 1] = 1;
  36. data[index + 2] = 0;
  37. }
  38. /**
  39. * The amount of shadow gradations.
  40. */
  41. public function get levels():uint
  42. {
  43. return _levels;
  44. }
  45. public function set levels(value:uint):void
  46. {
  47. _levels = value;
  48. }
  49. /**
  50. * The smoothness of the edge between 2 shading levels.
  51. */
  52. public function get smoothness():Number
  53. {
  54. return _smoothness;
  55. }
  56. public function set smoothness(value:Number):void
  57. {
  58. _smoothness = value;
  59. }
  60. /**
  61. * @inheritDoc
  62. */
  63. arcane override function cleanCompilationData():void
  64. {
  65. super.cleanCompilationData();
  66. _dataReg = null;
  67. }
  68. /**
  69. * @inheritDoc
  70. */
  71. override arcane function getFragmentPreLightingCode(vo:MethodVO, regCache:ShaderRegisterCache):String
  72. {
  73. _dataReg = regCache.getFreeFragmentConstant();
  74. vo.secondaryFragmentConstantsIndex = _dataReg.index*4;
  75. return super.getFragmentPreLightingCode(vo, regCache);
  76. }
  77. /**
  78. * @inheritDoc
  79. */
  80. override arcane function activate(vo:MethodVO, stage3DProxy:Stage3DProxy):void
  81. {
  82. super.activate(vo, stage3DProxy);
  83. var data:Vector.<Number> = vo.fragmentData;
  84. var index:int = vo.secondaryFragmentConstantsIndex;
  85. data[index] = _levels;
  86. data[index + 3] = _smoothness;
  87. }
  88. /**
  89. * Snaps the diffuse shading of the wrapped method to one of the levels.
  90. * @param vo The MethodVO used to compile the current shader.
  91. * @param t The register containing the diffuse strength in the "w" component.
  92. * @param regCache The register cache used for the shader compilation.
  93. * @param sharedRegisters The shared register data for this shader.
  94. * @return The AGAL fragment code for the method.
  95. */
  96. private function clampDiffuse(vo:MethodVO, t:ShaderRegisterElement, regCache:ShaderRegisterCache, sharedRegisters:ShaderRegisterData):String
  97. {
  98. return "mul " + t + ".w, " + t + ".w, " + _dataReg + ".x\n" +
  99. "frc " + t + ".z, " + t + ".w\n" +
  100. "sub " + t + ".y, " + t + ".w, " + t + ".z\n" +
  101. "mov " + t + ".x, " + _dataReg + ".x\n" +
  102. "sub " + t + ".x, " + t + ".x, " + _dataReg + ".y\n" +
  103. "rcp " + t + ".x," + t + ".x\n" +
  104. "mul " + t + ".w, " + t + ".y, " + t + ".x\n" +
  105. // previous clamped strength
  106. "sub " + t + ".y, " + t + ".w, " + t + ".x\n" +
  107. // fract/epsilon (so 0 - epsilon will become 0 - 1)
  108. "div " + t + ".z, " + t + ".z, " + _dataReg + ".w\n" +
  109. "sat " + t + ".z, " + t + ".z\n" +
  110. "mul " + t + ".w, " + t + ".w, " + t + ".z\n" +
  111. // 1-z
  112. "sub " + t + ".z, " + _dataReg + ".y, " + t + ".z\n" +
  113. "mul " + t + ".y, " + t + ".y, " + t + ".z\n" +
  114. "add " + t + ".w, " + t + ".w, " + t + ".y\n" +
  115. "sat " + t + ".w, " + t + ".w\n";
  116. }
  117. }
  118. }