2
0
Эх сурвалжийг харах

Add automatic smoothing support for SDF (#1006)

`BitmapFont.toSdfFonts` now defaults to auto-smoothing.
Text now automatically enables `smooth` if it wasn't explicitly set.
HtmlText now uses Text.smooth for SDF fonts.
Improve docs a bit.
Pavel Alexandrov 3 жил өмнө
parent
commit
381f8c0d9b

+ 1 - 1
h2d/Font.hx

@@ -138,7 +138,7 @@ enum FontType {
 
 		@param channel The channel that serves as distance data source.
 		@param alphaCutoff The distance value that is considered to be the edge. Usually should be 0.5.
-		@param smoothing The smoothing of edge. Lower value lead to sharper edges.
+		@param smoothing The smoothing of edge. Lower value lead to sharper edges. Value of -1 sets it to automatic.
 	**/
 	SignedDistanceField(channel : SDFChannel, alphaCutoff : Float, smoothing : Float);
 }

+ 2 - 1
h2d/HtmlText.hx

@@ -616,7 +616,8 @@ class HtmlText extends Text {
 							shader.channel = channel;
 							shader.alphaCutoff = alphaCutoff;
 							shader.smoothing = smoothing;
-							glyphs.smooth = true;
+							shader.autoSmoothing = smoothing == -1;
+							glyphs.smooth = this.smooth;
 							glyphs.addShader(shader);
 						default:
 					}

+ 3 - 0
h2d/Text.hx

@@ -157,9 +157,12 @@ class Text extends Drawable {
 						sdfShader = new h3d.shader.SignedDistanceField();
 						addShader(sdfShader);
 					}
+					// Automatically use linear sampling if not designated otherwise.
+					if (smooth == null) smooth = true;
 					sdfShader.alphaCutoff = alphaCutoff;
 					sdfShader.smoothing = smoothing;
 					sdfShader.channel = channel;
+					sdfShader.autoSmoothing = smoothing == -1;
 			}
 		}
 		if( glyphs != null ) glyphs.remove();

+ 7 - 1
h3d/shader/SignedDistanceField.hx

@@ -7,7 +7,12 @@ class SignedDistanceField extends hxsl.Shader {
 		@:import h3d.shader.Base2d;
 
 		// Mode of operation - single-channel or multi-channel.
+		// 0123 = RGBA, evertyhing else is MSDF.
 		@const var channel : Int = 0;
+		/**
+			Use automatic edge smoothing based on derivatives.
+		**/
+		@const var autoSmoothing : Bool = false;
 		/**
 			Variable used to determine the edge of the field. ( default : 0.5 ) 
 			Can be used to provide cheaper Outline for Text compared to Filter usage.
@@ -32,7 +37,8 @@ class SignedDistanceField extends hxsl.Shader {
 				else if (channel == 3) textureSample.a;
 				else median(textureSample.r, textureSample.g, textureSample.b);
 
-			textureColor = vec4(1.0, 1.0, 1.0, smoothstep(alphaCutoff - smoothing, alphaCutoff + smoothing, distance));
+			var smoothVal = autoSmoothing ? abs(fwidth(distance) * 0.5) : smoothing;
+			textureColor = vec4(1.0, 1.0, 1.0, smoothstep(alphaCutoff - smoothVal, alphaCutoff + smoothVal, distance));
 		}
 	}
 

+ 13 - 2
hxd/res/BitmapFont.hx

@@ -16,6 +16,11 @@ class BitmapFont extends Resource {
 		this.loader = hxd.res.Loader.currentInstance;
 	}
 
+	/**
+		Load and cache the font instance.
+
+		Because font instance is cached, operations like `resizeTo` should be performed on a copy of the font, to avoid affecting other text fields.
+	**/
 	public function toFont() : h2d.Font {
 		if ( font == null ) {
 			font = hxd.fmt.bfnt.FontParser.parse(entry.getBytes(), entry.path, resolveTile);
@@ -24,11 +29,17 @@ class BitmapFont extends Resource {
 	}
 
 	/**
-		Load and cache Signed Distance Field font with specified size, channel, alphaCutoff and smoothing. ( default : initial size, red, 0.5, 1 / 32 )
+		Load and cache Signed Distance Field font with specified size, channel, alphaCutoff and smoothing. ( default : initial size, red, 0.5, -1 )
 		For more information on SDF texture generation refer to this page: https://github.com/libgdx/libgdx/wiki/Distance-field-fonts
 		For more information on MSDF texture generation refer to this page: https://github.com/Chlumsky/msdfgen
+
+		Because font instance is cached, operations like `resizeTo` should be performed on a copy of the font, to avoid affecting other text fields.
+
+		@param channel The channel that serves as distance data source.
+		@param alphaCutoff The distance value that is considered to be the edge. Usually should be 0.5.
+		@param smoothing The smoothing of edge. Lower value lead to sharper edges. Value of -1 sets it to automatic.
 	**/
-	public function toSdfFont(?size:Int, channel : h2d.Font.SDFChannel = 0, alphaCutoff : Float = 0.5, smoothing : Float = 1 / 32 ) {
+	public function toSdfFont(?size:Int, channel : h2d.Font.SDFChannel = 0, alphaCutoff : Float = 0.5, smoothing : Float = -1 ) {
 		if ( sdfFonts == null ) sdfFonts = new Array();
 		if ( size == null ) size = toFont().size;
 		for ( font in sdfFonts ) {