/src/away3d/materials/methods/FilteredShadowMapMethod.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 174 lines · 121 code · 29 blank · 24 comment · 0 complexity · 11e13d80bfd7dd2f5b663cc29c40d4fe MD5 · raw file

  1. package away3d.materials.methods
  2. {
  3. import away3d.arcane;
  4. import away3d.core.managers.Stage3DProxy;
  5. import away3d.lights.DirectionalLight;
  6. import away3d.materials.compilation.ShaderRegisterCache;
  7. import away3d.materials.compilation.ShaderRegisterElement;
  8. use namespace arcane;
  9. /**
  10. * DitheredShadowMapMethod provides a softened shadowing technique by bilinearly interpolating shadow comparison
  11. * results of neighbouring pixels.
  12. */
  13. public class FilteredShadowMapMethod extends SimpleShadowMapMethodBase
  14. {
  15. /**
  16. * Creates a new BasicDiffuseMethod object.
  17. *
  18. * @param castingLight The light casting the shadow
  19. */
  20. public function FilteredShadowMapMethod(castingLight:DirectionalLight)
  21. {
  22. super(castingLight);
  23. }
  24. /**
  25. * @inheritDoc
  26. */
  27. override arcane function initConstants(vo:MethodVO):void
  28. {
  29. super.initConstants(vo);
  30. var fragmentData:Vector.<Number> = vo.fragmentData;
  31. var index:int = vo.fragmentConstantsIndex;
  32. fragmentData[index + 8] = .5;
  33. var size:int = castingLight.shadowMapper.depthMapSize;
  34. fragmentData[index + 9] = size;
  35. fragmentData[index + 10] = 1/size;
  36. }
  37. /**
  38. * @inheritDoc
  39. */
  40. override protected function getPlanarFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, targetReg:ShaderRegisterElement):String
  41. {
  42. var depthMapRegister:ShaderRegisterElement = regCache.getFreeTextureReg();
  43. var decReg:ShaderRegisterElement = regCache.getFreeFragmentConstant();
  44. var dataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant();
  45. // TODO: not used
  46. dataReg = dataReg;
  47. var customDataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant();
  48. var depthCol:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
  49. var uvReg:ShaderRegisterElement;
  50. var code:String = "";
  51. vo.fragmentConstantsIndex = decReg.index*4;
  52. regCache.addFragmentTempUsages(depthCol, 1);
  53. uvReg = regCache.getFreeFragmentVectorTemp();
  54. regCache.addFragmentTempUsages(uvReg, 1);
  55. code += "mov " + uvReg + ", " + _depthMapCoordReg + "\n" +
  56. "tex " + depthCol + ", " + _depthMapCoordReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" +
  57. "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" +
  58. "slt " + uvReg + ".z, " + _depthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow
  59. "add " + uvReg + ".x, " + _depthMapCoordReg + ".x, " + customDataReg + ".z\n" + // (1, 0)
  60. "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" +
  61. "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" +
  62. "slt " + uvReg + ".w, " + _depthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow
  63. "mul " + depthCol + ".x, " + _depthMapCoordReg + ".x, " + customDataReg + ".y\n" +
  64. "frc " + depthCol + ".x, " + depthCol + ".x\n" +
  65. "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" +
  66. "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" +
  67. "add " + targetReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" +
  68. "mov " + uvReg + ".x, " + _depthMapCoordReg + ".x\n" +
  69. "add " + uvReg + ".y, " + _depthMapCoordReg + ".y, " + customDataReg + ".z\n" + // (0, 1)
  70. "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" +
  71. "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" +
  72. "slt " + uvReg + ".z, " + _depthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow
  73. "add " + uvReg + ".x, " + _depthMapCoordReg + ".x, " + customDataReg + ".z\n" + // (1, 1)
  74. "tex " + depthCol + ", " + uvReg + ", " + depthMapRegister + " <2d, nearest, clamp>\n" +
  75. "dp4 " + depthCol + ".z, " + depthCol + ", " + decReg + "\n" +
  76. "slt " + uvReg + ".w, " + _depthMapCoordReg + ".z, " + depthCol + ".z\n" + // 0 if in shadow
  77. // recalculate fraction, since we ran out of registers :(
  78. "mul " + depthCol + ".x, " + _depthMapCoordReg + ".x, " + customDataReg + ".y\n" +
  79. "frc " + depthCol + ".x, " + depthCol + ".x\n" +
  80. "sub " + uvReg + ".w, " + uvReg + ".w, " + uvReg + ".z\n" +
  81. "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" +
  82. "add " + uvReg + ".w, " + uvReg + ".z, " + uvReg + ".w\n" +
  83. "mul " + depthCol + ".x, " + _depthMapCoordReg + ".y, " + customDataReg + ".y\n" +
  84. "frc " + depthCol + ".x, " + depthCol + ".x\n" +
  85. "sub " + uvReg + ".w, " + uvReg + ".w, " + targetReg + ".w\n" +
  86. "mul " + uvReg + ".w, " + uvReg + ".w, " + depthCol + ".x\n" +
  87. "add " + targetReg + ".w, " + targetReg + ".w, " + uvReg + ".w\n";
  88. regCache.removeFragmentTempUsage(depthCol);
  89. regCache.removeFragmentTempUsage(uvReg);
  90. vo.texturesIndex = depthMapRegister.index;
  91. return code;
  92. }
  93. /**
  94. * @inheritDoc
  95. */
  96. override arcane function activateForCascade(vo:MethodVO, stage3DProxy:Stage3DProxy):void
  97. {
  98. var size:int = _castingLight.shadowMapper.depthMapSize;
  99. var index:int = vo.secondaryFragmentConstantsIndex;
  100. var data:Vector.<Number> = vo.fragmentData;
  101. data[index] = size;
  102. data[index + 1] = 1/size;
  103. }
  104. /**
  105. * @inheritDoc
  106. */
  107. override arcane function getCascadeFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, decodeRegister:ShaderRegisterElement, depthTexture:ShaderRegisterElement, depthProjection:ShaderRegisterElement, targetRegister:ShaderRegisterElement):String
  108. {
  109. var code:String;
  110. var dataReg:ShaderRegisterElement = regCache.getFreeFragmentConstant();
  111. vo.secondaryFragmentConstantsIndex = dataReg.index*4;
  112. var temp:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
  113. regCache.addFragmentTempUsages(temp, 1);
  114. var predicate:ShaderRegisterElement = regCache.getFreeFragmentVectorTemp();
  115. regCache.addFragmentTempUsages(predicate, 1);
  116. code = "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" +
  117. "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" +
  118. "slt " + predicate + ".x, " + depthProjection + ".z, " + temp + ".z\n" +
  119. "add " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" +
  120. "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" +
  121. "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" +
  122. "slt " + predicate + ".z, " + depthProjection + ".z, " + temp + ".z\n" +
  123. "add " + depthProjection + ".y, " + depthProjection + ".y, " + dataReg + ".y\n" +
  124. "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" +
  125. "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" +
  126. "slt " + predicate + ".w, " + depthProjection + ".z, " + temp + ".z\n" +
  127. "sub " + depthProjection + ".x, " + depthProjection + ".x, " + dataReg + ".y\n" +
  128. "tex " + temp + ", " + depthProjection + ", " + depthTexture + " <2d, nearest, clamp>\n" +
  129. "dp4 " + temp + ".z, " + temp + ", " + decodeRegister + "\n" +
  130. "slt " + predicate + ".y, " + depthProjection + ".z, " + temp + ".z\n" +
  131. "mul " + temp + ".xy, " + depthProjection + ".xy, " + dataReg + ".x\n" +
  132. "frc " + temp + ".xy, " + temp + ".xy\n" +
  133. // some strange register juggling to prevent agal bugging out
  134. "sub " + depthProjection + ", " + predicate + ".xyzw, " + predicate + ".zwxy\n" +
  135. "mul " + depthProjection + ", " + depthProjection + ", " + temp + ".x\n" +
  136. "add " + predicate + ".xy, " + predicate + ".xy, " + depthProjection + ".zw\n" +
  137. "sub " + predicate + ".y, " + predicate + ".y, " + predicate + ".x\n" +
  138. "mul " + predicate + ".y, " + predicate + ".y, " + temp + ".y\n" +
  139. "add " + targetRegister + ".w, " + predicate + ".x, " + predicate + ".y\n";
  140. regCache.removeFragmentTempUsage(temp);
  141. regCache.removeFragmentTempUsage(predicate);
  142. return code;
  143. }
  144. }
  145. }