Browse Source

added FXAA support

Nicolas Cannasse 11 years ago
parent
commit
d1fbfaf7d5
1 changed files with 58 additions and 0 deletions
  1. 58 0
      h3d/pass/FXAA.hx

+ 58 - 0
h3d/pass/FXAA.hx

@@ -0,0 +1,58 @@
+package h3d.pass;
+
+private class FXAAShader extends h3d.shader.ScreenShader {
+
+	static var SRC = {
+
+		@param var delta : Vec2;
+		@param var texture : Sampler2D;
+
+		function fragment() {
+
+			var tuv = input.uv;
+
+			var nw = texture.get(tuv + vec2(-1, -1) * delta).rgb;
+			var ne = texture.get(tuv + vec2(1, -1) * delta).rgb;
+			var sw = texture.get(tuv + vec2(-1, 1) * delta).rgb;
+			var se = texture.get(tuv + vec2(1, 1) * delta).rgb;
+			var mid = texture.get(tuv).rgb;
+			var lumA = vec3(0.299, 0.587, 0.114);
+			var lumNW = nw.dot(lumA);
+			var lumNE = ne.dot(lumA);
+			var lumSW = sw.dot(lumA);
+			var lumSE = se.dot(lumA);
+			var lumMid = mid.dot(lumA);
+			var lumMin = min(lumMid, min(min(lumNW, lumNE), min(lumSW, lumSE)));
+			var lumMax = max(lumMid, max(max(lumNW, lumNE), max(lumSW, lumSE)));
+			var dir : Vec2;
+			dir.x = -((lumNW + lumNE) - (lumSW + lumSE));
+			dir.y = ((lumNW + lumSW) - (lumNE + lumSE));
+			var dirReduce = max((lumNW + lumNE + lumSW + lumSE) * (0.25 / 128), 1. / 8);
+			var rcpDirMin = 1 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+			dir = min(vec2(8, 8), max(vec2(-8, -8), dir * rcpDirMin)) * delta;
+
+			var rgbA = 0.5 * (texture.get(tuv + dir * (1.0 / 3.0 - 0.5)).xyz + texture.get(tuv + dir * (2.0 / 3.0 - 0.5)).xyz);
+			var rgbB = rgbA * 0.5 + 0.25 * (texture.get(tuv + dir * -0.5).xyz + texture.get(tuv + dir * 0.5).xyz);
+			var lumB = dot(rgbB, lumA);
+			var color : Vec4;
+			var cmp = vec2(lumB, lumB) >= vec2(lumMin, -lumMax);
+			color.xyz = mix(rgbB, rgbA, cmp.x * cmp.y);
+			color.a = 1.;
+			output.color = color;
+		}
+	}
+}
+
+class FXAA extends ScreenFx<FXAAShader> {
+
+	public function new() {
+		super(new FXAAShader());
+	}
+
+	public function apply( texture : h3d.mat.Texture ) {
+		shader.texture = texture;
+		shader.delta.set(1 / texture.width, 1 / texture.height);
+		render();
+	}
+
+}