Displacement.hx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package h2d.filter;
  2. import hxd.Math;
  3. /**
  4. Applies a normal map to the filtered Object in order to displace pixels.
  5. Uses red and green channels to displaces horizontal and vertical axes accordingly.
  6. **/
  7. class Displacement extends Filter {
  8. /**
  9. The normal map used for displacement lookup.
  10. **/
  11. public var normalMap : h2d.Tile;
  12. /**
  13. Horizontal displacement distance in pixels.
  14. **/
  15. public var dispX : Float;
  16. /**
  17. Vertical displacement distance in pixels.
  18. **/
  19. public var dispY : Float;
  20. /**
  21. When enabled, the displacement map will wrap around when lookup reaches its edges.
  22. Otherwise out-of-bounds values are clamped to the border.
  23. **/
  24. public var wrap(default, set) : Bool;
  25. var disp = new h3d.pass.ScreenFx(new h3d.shader.Displacement());
  26. /**
  27. Create a new displacement filter.
  28. @param normalMap The normal map used for displacement lookup.
  29. @param dispX Horizontal displacement distance in pixels.
  30. @param dispY Vertical displacement distance in pixels.
  31. @param wrap Wrap normal map around when lookup UV goes out of bounds.
  32. **/
  33. public function new( normalMap : h2d.Tile, dispX : Float = 5., dispY = 5., wrap = true ) {
  34. super();
  35. this.normalMap = normalMap;
  36. this.dispX = dispX;
  37. this.dispY = dispY;
  38. this.wrap = wrap;
  39. }
  40. function set_wrap(w) {
  41. var t = normalMap == null ? null : normalMap.getTexture();
  42. if( t != null ) t.wrap = w ? Repeat : Clamp;
  43. return wrap = w;
  44. }
  45. override function sync(ctx, s) {
  46. boundsExtend = Math.max(Math.abs(dispX), Math.abs(dispY));
  47. }
  48. override function draw( ctx : RenderContext, t : h2d.Tile ) {
  49. var out = ctx.textures.allocTileTarget("displacementOutput", t);
  50. ctx.engine.pushTarget(out);
  51. var s = disp.shader;
  52. s.texture = t.getTexture();
  53. s.displacement.set(dispX / t.width, dispY / t.height);
  54. s.normalMap = normalMap.getTexture();
  55. s.normalPos.set(normalMap.u, normalMap.v);
  56. s.normalScale.set(normalMap.u2 - normalMap.u, normalMap.v2 - normalMap.v);
  57. disp.render();
  58. ctx.engine.popTarget();
  59. return h2d.Tile.fromTexture(out);
  60. }
  61. }