Quellcode durchsuchen

Outline filter (#413)

Leo Bergman vor 7 Jahren
Ursprung
Commit
6229a2ad03
3 geänderte Dateien mit 138 neuen und 0 gelöschten Zeilen
  1. 43 0
      h2d/filter/Outline.hx
  2. 64 0
      h3d/pass/Outline.hx
  3. 31 0
      h3d/shader/Outline2D.hx

+ 43 - 0
h2d/filter/Outline.hx

@@ -0,0 +1,43 @@
+package h2d.filter;
+
+class Outline extends Filter {
+	public var size(default, set) : Float;
+	public var color(default, set) : Int;
+	public var quality(default, set) : Float;
+	public var multiplyAlpha(default, set) : Bool;
+
+	var pass : h3d.pass.Outline;
+
+	public function new(size = 4.0, color = 0xFF000000, quality = 0.3, multiplyAlpha = true) {
+		super();
+		smooth = true;
+		pass = new h3d.pass.Outline(size, color, quality, multiplyAlpha);
+	}
+
+	inline function get_size() return pass.size;
+
+	inline function set_size(v) return pass.size = v;
+
+	inline function get_color() return pass.color;
+
+	inline function set_color(v) return pass.color = v;
+
+	inline function get_quality() return pass.quality;
+
+	inline function set_quality(v) return pass.quality = v;
+
+	inline function set_multiplyAlpha(v) return pass.multiplyAlpha = v;
+
+	override function sync(ctx : RenderContext, s : Sprite) {
+		boundsExtend = pass.size * 2;
+	}
+
+	override function draw(ctx : RenderContext, t : h2d.Tile) {
+		var out = t.getTexture();
+		var old = out.filter;
+		out.filter = Linear;
+		pass.apply(ctx, out);
+		out.filter = old;
+		return t;
+	}
+}

+ 64 - 0
h3d/pass/Outline.hx

@@ -0,0 +1,64 @@
+package h3d.pass;
+
+@ignore("shader")
+class Outline extends ScreenFx<h3d.shader.Outline2D> {
+	public var size(default, set) : Float;
+	public var color(default, set) : Int;
+	public var quality(default, set) : Float;
+	public var multiplyAlpha(default, set) : Bool;
+
+	public function new(size = 4.0, color = 0xFF000000, quality = 0.3, multiplyAlpha = true) {
+		super(new h3d.shader.Outline2D());
+		this.size = size;
+		this.color = color;
+		this.quality = quality;
+		this.multiplyAlpha = multiplyAlpha;
+	}
+
+	public function apply(ctx : h3d.impl.RenderContext, src : h3d.mat.Texture, ?output : h3d.mat.Texture) {
+		if (output == null)
+			output = src;
+		var tmp = ctx.textures.allocTarget(src.name + "OutlineTmp", src.width, src.height, false, src.format, [Target]);
+		shader.color.setColor(color);
+		shader.size.set(size / src.width, size / src.height);
+		shader.samples = Std.int(Math.max(quality * 100, 1));
+		shader.multiplyAlpha = multiplyAlpha ? 0 : 1;
+
+		shader.texture = src;
+		engine.pushTarget(tmp);
+		render();
+		engine.popTarget();
+
+		shader.texture = tmp;
+		var outDepth = output.depthBuffer;
+		output.depthBuffer = null;
+		engine.pushTarget(output);
+		render();
+		engine.popTarget();
+		output.depthBuffer = outDepth;
+	}
+
+	function set_size(s) {
+		if (size == s)
+			return s;
+		return size = s;
+	}
+
+	function set_color(c) {
+		if (color == c)
+			return c;
+		return color = c;
+	}
+
+	function set_quality(q) {
+		if (quality == q)
+			return q;
+		return quality = q;
+	}
+
+	function set_multiplyAlpha(m) {
+		if (multiplyAlpha == m)
+			return m;
+		return multiplyAlpha = m;
+	}
+}

+ 31 - 0
h3d/shader/Outline2D.hx

@@ -0,0 +1,31 @@
+package h3d.shader;
+
+class Outline2D extends ScreenShader {
+	static var SRC = {
+		@param var texture : Sampler2D;
+		@param var size : Vec2;
+		@param @const var samples : Int;
+		@param var color : Vec4;
+		@param @const var multiplyAlpha : Int;
+		function fragment() {
+			var ownColor : Vec4 = texture.get(input.uv);
+			var maxAlpha = 0.;
+			var curColor : Vec4;
+			var displaced : Vec2;
+			var angle = 0.;
+			var doublePi = 6.28318530717958647692528;
+			var step = doublePi / samples;
+			@unroll for (i in 0...samples) {
+				angle += step;
+				displaced.x = input.uv.x + size.x * cos(angle);
+				displaced.y = input.uv.y + size.y * sin(angle);
+				curColor = texture.get(displaced);
+				maxAlpha = max(maxAlpha, curColor.a);
+			}
+			var resultAlpha = max(maxAlpha, ownColor.a);
+			var resultColor = ownColor.rgb + color.rgb * (1. - ownColor.a);
+			var out = resultColor * max(float(multiplyAlpha), resultAlpha);
+			output.color = vec4(out, resultAlpha);
+		}
+	};
+}