@babylonjs/addons 8.8.5 → 8.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/index.d.ts +2 -2
  2. package/index.js +3 -2
  3. package/index.js.map +1 -1
  4. package/msdfText/fontAsset.d.ts +5 -2
  5. package/msdfText/fontAsset.js +13 -2
  6. package/msdfText/fontAsset.js.map +1 -1
  7. package/msdfText/index.d.ts +5 -0
  8. package/msdfText/index.js +6 -0
  9. package/msdfText/index.js.map +1 -1
  10. package/msdfText/paragraphOptions.d.ts +2 -2
  11. package/msdfText/paragraphOptions.js +1 -2
  12. package/msdfText/paragraphOptions.js.map +1 -1
  13. package/msdfText/sdf/index.d.ts +5 -0
  14. package/msdfText/sdf/index.js +6 -0
  15. package/msdfText/sdf/index.js.map +1 -0
  16. package/msdfText/sdf/paragraph.js +11 -9
  17. package/msdfText/sdf/paragraph.js.map +1 -1
  18. package/msdfText/{webgpu/vertex.d.ts → shaders/msdf.fragment.d.ts} +1 -1
  19. package/msdfText/shaders/msdf.fragment.js +14 -0
  20. package/msdfText/shaders/msdf.fragment.js.map +1 -0
  21. package/msdfText/shaders/msdf.vertex.js +17 -0
  22. package/msdfText/shaders/msdf.vertex.js.map +1 -0
  23. package/msdfText/{webgl/fragment.d.ts → shadersWGSL/msdf.fragment.d.ts} +1 -1
  24. package/msdfText/shadersWGSL/msdf.fragment.js +13 -0
  25. package/msdfText/shadersWGSL/msdf.fragment.js.map +1 -0
  26. package/msdfText/{webgpu/fragment.d.ts → shadersWGSL/msdf.vertex.d.ts} +1 -1
  27. package/msdfText/shadersWGSL/msdf.vertex.js +21 -0
  28. package/msdfText/shadersWGSL/msdf.vertex.js.map +1 -0
  29. package/msdfText/textRenderer.d.ts +33 -4
  30. package/msdfText/textRenderer.js +58 -46
  31. package/msdfText/textRenderer.js.map +1 -1
  32. package/package.json +2 -2
  33. package/msdfText/webgl/fragment.js +0 -45
  34. package/msdfText/webgl/fragment.js.map +0 -1
  35. package/msdfText/webgl/vertex.js +0 -25
  36. package/msdfText/webgl/vertex.js.map +0 -1
  37. package/msdfText/webgpu/fragment.js +0 -47
  38. package/msdfText/webgpu/fragment.js.map +0 -1
  39. package/msdfText/webgpu/vertex.js +0 -31
  40. package/msdfText/webgpu/vertex.js.map +0 -1
  41. /package/msdfText/{webgl/vertex.d.ts → shaders/msdf.vertex.d.ts} +0 -0
package/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./htmlMesh.js";
2
- export * from "./msdfText.js";
1
+ export * from "./htmlMesh/index.js";
2
+ export * from "./msdfText/index.js";
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export * from "./htmlMesh.js";
2
- export * from "./msdfText.js";
1
+ /* eslint-disable import/no-internal-modules */
2
+ export * from "./htmlMesh/index.js";
3
+ export * from "./msdfText/index.js";
3
4
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dev/addons/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./htmlMesh\";\nexport * from \"./msdfText\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dev/addons/src/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC","sourcesContent":["/* eslint-disable import/no-internal-modules */\nexport * from \"./htmlMesh/index\";\nexport * from \"./msdfText/index\";\n"]}
@@ -1,10 +1,11 @@
1
+ import type { IDisposable, Scene } from "@babylonjs/core/scene.js";
1
2
  import type { BMFontChar } from "./sdf/bmFont.js";
2
3
  import type { SdfFont } from "./sdf/font.js";
3
4
  import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
4
5
  /**
5
6
  * Class representing a font asset for SDF (Signed Distance Field) rendering.
6
7
  */
7
- export declare class FontAsset {
8
+ export declare class FontAsset implements IDisposable {
8
9
  private readonly _chars;
9
10
  private readonly _charsRegex;
10
11
  private readonly _kernings;
@@ -22,8 +23,10 @@ export declare class FontAsset {
22
23
  * Creates a new FontAsset instance.
23
24
  * @param definitionData defines the font data in JSON format.
24
25
  * @param textureUrl defines the url of the texture to use for the font.
26
+ * @param scene defines the hosting scene.
25
27
  */
26
- constructor(definitionData: string, textureUrl: string);
28
+ constructor(definitionData: string, textureUrl: string, scene?: Scene);
29
+ dispose(): void;
27
30
  private _updateFallbacks;
28
31
  /** @internal */
29
32
  _getChar(charCode: number): BMFontChar;
@@ -12,8 +12,9 @@ export class FontAsset {
12
12
  * Creates a new FontAsset instance.
13
13
  * @param definitionData defines the font data in JSON format.
14
14
  * @param textureUrl defines the url of the texture to use for the font.
15
+ * @param scene defines the hosting scene.
15
16
  */
16
- constructor(definitionData, textureUrl) {
17
+ constructor(definitionData, textureUrl, scene) {
17
18
  this._chars = new Map();
18
19
  this._kernings = new Map();
19
20
  this._font = JSON.parse(definitionData);
@@ -31,7 +32,17 @@ export class FontAsset {
31
32
  this._charsRegex = new RegExp(`[${this._font.chars.map((c) => c.char.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")).join("")}]`, "g");
32
33
  this._updateFallbacks();
33
34
  this.scale = 1 / this._font.info.size;
34
- this.textures = this._font.pages.map((page) => new Texture(page, undefined, { noMipmap: true, invertY: false }));
35
+ this.textures = this._font.pages.map((page) => {
36
+ const texture = new Texture(page, scene, { noMipmap: false, invertY: false });
37
+ texture.anisotropicFilteringLevel = 16;
38
+ return texture;
39
+ });
40
+ }
41
+ dispose() {
42
+ for (const texture of this.textures) {
43
+ texture.dispose();
44
+ }
45
+ this.textures.length = 0;
35
46
  }
36
47
  _updateFallbacks() {
37
48
  if (!this._chars.has(CharCode.SPACE)) {
@@ -1 +1 @@
1
- {"version":3,"file":"fontAsset.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/fontAsset.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BMFontChar } from \"./sdf/bmFont\";\r\nimport type { SdfFont } from \"./sdf/font\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nenum CharCode {\r\n SPACE = 32,\r\n TOFU = 0xfffc,\r\n}\r\n\r\n/**\r\n * Class representing a font asset for SDF (Signed Distance Field) rendering.\r\n */\r\nexport class FontAsset {\r\n private readonly _chars = new Map<number, BMFontChar>();\r\n private readonly _charsRegex: RegExp;\r\n private readonly _kernings = new Map<number, Map<number, number>>();\r\n\r\n /** @internal */\r\n public readonly _font: SdfFont;\r\n\r\n /**\r\n * Gets the font scale value\r\n */\r\n public readonly scale: number;\r\n\r\n /**\r\n * Gets the list of used textures\r\n */\r\n public readonly textures: Texture[];\r\n\r\n /**\r\n * Creates a new FontAsset instance.\r\n * @param definitionData defines the font data in JSON format.\r\n * @param textureUrl defines the url of the texture to use for the font.\r\n */\r\n public constructor(definitionData: string, textureUrl: string) {\r\n this._font = JSON.parse(definitionData) as SdfFont;\r\n // So far we only consider one page\r\n this._font.pages = [textureUrl];\r\n\r\n this._font.chars.forEach((char) => this._chars.set(char.id, char));\r\n this._font.kernings.forEach((kerning) => {\r\n let submap = this._kernings.get(kerning.first);\r\n if (!submap) {\r\n submap = new Map();\r\n this._kernings.set(kerning.first, submap);\r\n }\r\n submap.set(kerning.second, kerning.amount);\r\n });\r\n this._charsRegex = new RegExp(`[${this._font.chars.map((c) => c.char.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\")).join(\"\")}]`, \"g\");\r\n\r\n this._updateFallbacks();\r\n\r\n this.scale = 1 / this._font.info.size;\r\n this.textures = this._font.pages.map((page) => new Texture(page, undefined, { noMipmap: true, invertY: false }));\r\n }\r\n\r\n private _updateFallbacks() {\r\n if (!this._chars.has(CharCode.SPACE)) {\r\n this._chars.set(CharCode.SPACE, {\r\n id: CharCode.SPACE,\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \" \",\r\n });\r\n }\r\n\r\n if (!this._chars.has(CharCode.TOFU)) {\r\n this._chars.set(CharCode.TOFU, {\r\n id: CharCode.TOFU,\r\n x: 0,\r\n y: 0,\r\n width: this._font.info.size,\r\n height: this._font.info.size,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \"￿\",\r\n });\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _getChar(charCode: number) {\r\n return this._chars.get(charCode) || this._chars.get(CharCode.TOFU)!;\r\n }\r\n\r\n /** @internal */\r\n public _getKerning(first: number, second: number) {\r\n return this._kernings.get(first)?.get(second) || 0;\r\n }\r\n\r\n /** @internal */\r\n public _unsupportedChars(text: string) {\r\n return text.replace(this._charsRegex, \"\");\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"fontAsset.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/fontAsset.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IDisposable, Scene } from \"core/scene\";\r\nimport type { BMFontChar } from \"./sdf/bmFont\";\r\nimport type { SdfFont } from \"./sdf/font\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nenum CharCode {\r\n SPACE = 32,\r\n TOFU = 0xfffc,\r\n}\r\n\r\n/**\r\n * Class representing a font asset for SDF (Signed Distance Field) rendering.\r\n */\r\nexport class FontAsset implements IDisposable {\r\n private readonly _chars = new Map<number, BMFontChar>();\r\n private readonly _charsRegex: RegExp;\r\n private readonly _kernings = new Map<number, Map<number, number>>();\r\n\r\n /** @internal */\r\n public readonly _font: SdfFont;\r\n\r\n /**\r\n * Gets the font scale value\r\n */\r\n public readonly scale: number;\r\n\r\n /**\r\n * Gets the list of used textures\r\n */\r\n public readonly textures: Texture[];\r\n\r\n /**\r\n * Creates a new FontAsset instance.\r\n * @param definitionData defines the font data in JSON format.\r\n * @param textureUrl defines the url of the texture to use for the font.\r\n * @param scene defines the hosting scene.\r\n */\r\n public constructor(definitionData: string, textureUrl: string, scene?: Scene) {\r\n this._font = JSON.parse(definitionData) as SdfFont;\r\n // So far we only consider one page\r\n this._font.pages = [textureUrl];\r\n\r\n this._font.chars.forEach((char) => this._chars.set(char.id, char));\r\n this._font.kernings.forEach((kerning) => {\r\n let submap = this._kernings.get(kerning.first);\r\n if (!submap) {\r\n submap = new Map();\r\n this._kernings.set(kerning.first, submap);\r\n }\r\n submap.set(kerning.second, kerning.amount);\r\n });\r\n this._charsRegex = new RegExp(`[${this._font.chars.map((c) => c.char.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\")).join(\"\")}]`, \"g\");\r\n\r\n this._updateFallbacks();\r\n\r\n this.scale = 1 / this._font.info.size;\r\n this.textures = this._font.pages.map((page) => {\r\n const texture = new Texture(page, scene, { noMipmap: false, invertY: false });\r\n texture.anisotropicFilteringLevel = 16;\r\n return texture;\r\n });\r\n }\r\n\r\n dispose(): void {\r\n for (const texture of this.textures) {\r\n texture.dispose();\r\n }\r\n this.textures.length = 0;\r\n }\r\n\r\n private _updateFallbacks() {\r\n if (!this._chars.has(CharCode.SPACE)) {\r\n this._chars.set(CharCode.SPACE, {\r\n id: CharCode.SPACE,\r\n x: 0,\r\n y: 0,\r\n width: 0,\r\n height: 0,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \" \",\r\n });\r\n }\r\n\r\n if (!this._chars.has(CharCode.TOFU)) {\r\n this._chars.set(CharCode.TOFU, {\r\n id: CharCode.TOFU,\r\n x: 0,\r\n y: 0,\r\n width: this._font.info.size,\r\n height: this._font.info.size,\r\n xoffset: 0,\r\n yoffset: 0,\r\n xadvance: this._font.info.size * 0.5,\r\n page: -1,\r\n chnl: -1,\r\n index: -1,\r\n char: \"￿\",\r\n });\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _getChar(charCode: number) {\r\n return this._chars.get(charCode) || this._chars.get(CharCode.TOFU)!;\r\n }\r\n\r\n /** @internal */\r\n public _getKerning(first: number, second: number) {\r\n return this._kernings.get(first)?.get(second) || 0;\r\n }\r\n\r\n /** @internal */\r\n public _unsupportedChars(text: string) {\r\n return text.replace(this._charsRegex, \"\");\r\n }\r\n}\r\n"]}
@@ -1,3 +1,8 @@
1
1
  export * from "./fontAsset.js";
2
2
  export * from "./paragraphOptions.js";
3
3
  export * from "./textRenderer.js";
4
+ export * from "./sdf/index.js";
5
+ export * from "./shaders/msdf.vertex.js";
6
+ export * from "./shaders/msdf.fragment.js";
7
+ export * from "./shadersWGSL/msdf.vertex.js";
8
+ export * from "./shadersWGSL/msdf.fragment.js";
package/msdfText/index.js CHANGED
@@ -1,4 +1,10 @@
1
+ /* eslint-disable import/no-internal-modules */
1
2
  export * from "./fontAsset.js";
2
3
  export * from "./paragraphOptions.js";
3
4
  export * from "./textRenderer.js";
5
+ export * from "./sdf/index.js";
6
+ export * from "./shaders/msdf.vertex.js";
7
+ export * from "./shaders/msdf.fragment.js";
8
+ export * from "./shadersWGSL/msdf.vertex.js";
9
+ export * from "./shadersWGSL/msdf.fragment.js";
4
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from \"./fontAsset\";\r\nexport * from \"./paragraphOptions\";\r\nexport * from \"./textRenderer\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC","sourcesContent":["/* eslint-disable import/no-internal-modules */\r\nexport * from \"./fontAsset\";\r\nexport * from \"./paragraphOptions\";\r\nexport * from \"./textRenderer\";\r\nexport * from \"./sdf/index\";\r\nexport * from \"./shaders/msdf.vertex\";\r\nexport * from \"./shaders/msdf.fragment\";\r\nexport * from \"./shadersWGSL/msdf.vertex\";\r\nexport * from \"./shadersWGSL/msdf.fragment\";\r\n"]}
@@ -1,4 +1,4 @@
1
- import { Vector2 } from "@babylonjs/core/Maths/math.vector.js";
1
+ import type { IVector2Like } from "@babylonjs/core/Maths.js";
2
2
  /** @internal */
3
3
  export type ParagraphOptions = {
4
4
  maxWidth: number;
@@ -7,7 +7,7 @@ export type ParagraphOptions = {
7
7
  tabSize: number;
8
8
  whiteSpace: "pre-line";
9
9
  textAlign: "left" | "right" | "center";
10
- translate: Vector2 | undefined;
10
+ translate: IVector2Like | undefined;
11
11
  };
12
12
  /** @internal */
13
13
  export declare const DefaultParagraphOptions: ParagraphOptions;
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable jsdoc/require-jsdoc */
2
- import { Vector2 } from "@babylonjs/core/Maths/math.vector.js";
3
2
  /** @internal */
4
3
  export const DefaultParagraphOptions = {
5
4
  maxWidth: Infinity,
@@ -8,6 +7,6 @@ export const DefaultParagraphOptions = {
8
7
  tabSize: 4,
9
8
  whiteSpace: "pre-line",
10
9
  textAlign: "center",
11
- translate: new Vector2(-0.5, -0.5),
10
+ translate: { x: -0.5, y: -0.5 },
12
11
  };
13
12
  //# sourceMappingURL=paragraphOptions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paragraphOptions.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/paragraphOptions.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,OAAO,EAAE,6CAA+B;AAajD,gBAAgB;AAChB,MAAM,CAAC,MAAM,uBAAuB,GAAqB;IACrD,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,CAAC;IACb,aAAa,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC;CACrC,CAAC","sourcesContent":["/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport { Vector2 } from \"core/Maths/math.vector\";\r\n\r\n/** @internal */\r\nexport type ParagraphOptions = {\r\n maxWidth: number;\r\n lineHeight: number;\r\n letterSpacing: number;\r\n tabSize: number;\r\n whiteSpace: /* 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | */ \"pre-line\" /* | 'break-spaces'*/;\r\n textAlign: \"left\" | \"right\" | \"center\" /* | 'justify'*/;\r\n translate: Vector2 | undefined;\r\n};\r\n\r\n/** @internal */\r\nexport const DefaultParagraphOptions: ParagraphOptions = {\r\n maxWidth: Infinity,\r\n lineHeight: 1,\r\n letterSpacing: 1,\r\n tabSize: 4,\r\n whiteSpace: \"pre-line\",\r\n textAlign: \"center\",\r\n translate: new Vector2(-0.5, -0.5),\r\n};\r\n"]}
1
+ {"version":3,"file":"paragraphOptions.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/paragraphOptions.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAexC,gBAAgB;AAChB,MAAM,CAAC,MAAM,uBAAuB,GAAqB;IACrD,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,CAAC;IACb,aAAa,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;IACV,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE;CAClC,CAAC","sourcesContent":["/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport type { IVector2Like } from \"core/Maths\";\r\n\r\n/** @internal */\r\nexport type ParagraphOptions = {\r\n maxWidth: number;\r\n lineHeight: number;\r\n letterSpacing: number;\r\n tabSize: number;\r\n whiteSpace: /* 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | */ \"pre-line\" /* | 'break-spaces'*/;\r\n textAlign: \"left\" | \"right\" | \"center\" /* | 'justify'*/;\r\n translate: IVector2Like | undefined;\r\n};\r\n\r\n/** @internal */\r\nexport const DefaultParagraphOptions: ParagraphOptions = {\r\n maxWidth: Infinity,\r\n lineHeight: 1,\r\n letterSpacing: 1,\r\n tabSize: 4,\r\n whiteSpace: \"pre-line\",\r\n textAlign: \"center\",\r\n translate: { x: -0.5, y: -0.5 },\r\n};\r\n"]}
@@ -0,0 +1,5 @@
1
+ export * from "./bmFont.js";
2
+ export * from "./font.js";
3
+ export * from "./glyph.js";
4
+ export * from "./line.js";
5
+ export * from "./paragraph.js";
@@ -0,0 +1,6 @@
1
+ export * from "./bmFont.js";
2
+ export * from "./font.js";
3
+ export * from "./glyph.js";
4
+ export * from "./line.js";
5
+ export * from "./paragraph.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/sdf/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./bmFont\";\nexport * from \"./font\";\nexport * from \"./glyph\";\nexport * from \"./line\";\nexport * from \"./paragraph\";\n"]}
@@ -38,14 +38,13 @@ export class SdfTextParagraph {
38
38
  return 0;
39
39
  }
40
40
  })();
41
- const translate = this.options.translate?.multiplyByFloats(width, height);
42
- line.glyphs.forEach((glyph) => {
41
+ const x = this.options.translate ? this.options.translate.x * width : 0;
42
+ const y = this.options.translate ? this.options.translate.y * height : 0;
43
+ for (const glyph of line.glyphs) {
43
44
  glyph.x += anchor;
44
- if (translate) {
45
- glyph.x += translate.x;
46
- glyph.y += translate.y;
47
- }
48
- });
45
+ glyph.x += x;
46
+ glyph.y += y;
47
+ }
49
48
  });
50
49
  }
51
50
  const glyphs = lines.flatMap((line) => line.glyphs);
@@ -87,7 +86,7 @@ export class SdfTextParagraph {
87
86
  const char = this.fontAsset._getChar(charCode);
88
87
  const charWidth = char.width;
89
88
  const kerning = lastChar ? this.fontAsset._getKerning(lastChar.id, char.id) : 0;
90
- currentCursor += kerning + char.xoffset;
89
+ currentCursor += kerning;
91
90
  const newWidth = currentCursor + charWidth;
92
91
  const cursorProgress = char.xadvance + this.options.letterSpacing;
93
92
  const nextPosition = currentCursor + cursorProgress;
@@ -103,7 +102,7 @@ export class SdfTextParagraph {
103
102
  currentGlyphs = [];
104
103
  }
105
104
  const x = currentCursor;
106
- const y = currentLine * this.lineHeight + char.yoffset;
105
+ const y = currentLine * this.lineHeight;
107
106
  currentGlyphs.push({
108
107
  char,
109
108
  line: currentLine,
@@ -122,6 +121,9 @@ export class SdfTextParagraph {
122
121
  }
123
122
  }
124
123
  if (currentGlyphs.length > 0) {
124
+ if (lastChar) {
125
+ // currentWidth += lastChar.xadvance;
126
+ }
125
127
  pushCurrentLine();
126
128
  }
127
129
  return lines;
@@ -1 +1 @@
1
- {"version":3,"file":"paragraph.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/sdf/paragraph.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAyB,MAAM,qBAAqB,CAAC;AAKrF,gBAAgB;AAChB,MAAM,OAAO,gBAAgB;IAGzB,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5E,CAAC;IAQD,YACoB,IAAY,EACZ,SAAoB,EACpC,OAAmC;QAFnB,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAW;QAGpC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,uBAAuB,EAAE,GAAG,OAAO,EAAE,CAAC;QAE1D,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAE/E,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAEO,eAAe,CAAC,IAAY;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAkB,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;QAE9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC9D,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACnB,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;oBACjB,QAAQ,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;wBAC7B,KAAK,OAAO;4BACR,OAAO,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;wBAC9B,KAAK,QAAQ;4BACT,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBACpC,KAAK,MAAM,CAAC;wBACZ;4BACI,OAAO,CAAC,CAAC;oBACjB,CAAC;gBACL,CAAC,CAAC,EAAE,CAAC;gBACL,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC1E,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC1B,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC;oBAClB,IAAI,SAAS,EAAE,CAAC;wBACZ,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;wBACvB,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEpD,OAAO;YACH,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7B,KAAK;YACL,MAAM;YACN,KAAK;YACL,MAAM;SACT,CAAC;IACN,CAAC;IAEO,WAAW,CAAC,IAAY;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEO,SAAS,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,IAAY,EAAE,UAAU,GAAG,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAe,CAAC;QAEvC,IAAI,WAAW,GAAG,UAAU,CAAC;QAC7B,IAAI,aAAa,GAAG,IAAI,KAAK,EAAY,CAAC;QAC1C,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,QAAgC,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,MAAM,eAAe,GAAG,GAAG,EAAE;YACzB,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;gBAC5B,MAAM,EAAE,aAAa;gBACrB,KAAK,EAAE,KAAK;gBACZ,GAAG,EAAE,GAAG;gBACR,KAAK,EAAE,YAAY;aACtB,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,GAAG,CAAC;YACd,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;YAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEhF,aAAa,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YACxC,MAAM,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;YAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;YAClE,MAAM,YAAY,GAAG,aAAa,GAAG,cAAc,CAAC;YAEpD,MAAM,WAAW,GAAG,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YAE7F,IAAI,WAAW,EAAE,CAAC;gBACd,eAAe,EAAE,CAAC;gBAElB,WAAW,EAAE,CAAC;gBACd,QAAQ,GAAG,SAAS,CAAC;gBACrB,aAAa,GAAG,CAAC,CAAC;gBAClB,YAAY,GAAG,CAAC,CAAC;gBACjB,KAAK,GAAG,GAAG,CAAC;gBACZ,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;gBAChB,aAAa,GAAG,EAAE,CAAC;YACvB,CAAC;YAED,MAAM,CAAC,GAAG,aAAa,CAAC;YACxB,MAAM,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;YAEvD,aAAa,CAAC,IAAI,CAAC;gBACf,IAAI;gBACJ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,aAAa,CAAC,MAAM;gBAC9B,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,CAAC;aACP,CAAC,CAAC;YAEH,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,aAAa,GAAG,YAAY,CAAC;gBAC7B,YAAY,GAAG,QAAQ,CAAC;gBACxB,GAAG,EAAE,CAAC;YACV,CAAC;iBAAM,CAAC;gBACJ,aAAa,GAAG,cAAc,CAAC;YACnC,CAAC;QACL,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,eAAe,EAAE,CAAC;QACtB,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ","sourcesContent":["/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { FontAsset } from \"../fontAsset\";\r\nimport { DefaultParagraphOptions, type ParagraphOptions } from \"../paragraphOptions\";\r\nimport type { BMFontChar } from \"./bmFont\";\r\nimport type { SdfGlyph } from \"./glyph\";\r\nimport type { SdfTextLine } from \"./line\";\r\n\r\n/** @internal */\r\nexport class SdfTextParagraph {\r\n public readonly options: ParagraphOptions;\r\n\r\n get lineHeight() {\r\n return this.fontAsset._font.common.lineHeight * this.options.lineHeight;\r\n }\r\n\r\n readonly paragraph;\r\n readonly lines;\r\n readonly width;\r\n readonly height;\r\n readonly glyphs;\r\n\r\n constructor(\r\n public readonly text: string,\r\n public readonly fontAsset: FontAsset,\r\n options?: Partial<ParagraphOptions>\r\n ) {\r\n this.options = { ...DefaultParagraphOptions, ...options };\r\n\r\n const { paragraph, lines, glyphs, width, height } = this._computeMetrics(text);\r\n\r\n this.paragraph = paragraph;\r\n this.lines = lines;\r\n this.glyphs = glyphs;\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n private _computeMetrics(text: string) {\r\n const collapsed = this._collapse(text);\r\n const breaked = this._breakLines(collapsed);\r\n const trimmed = breaked.map((line) => line.trim());\r\n\r\n const lines: SdfTextLine[] = [];\r\n for (const line of trimmed) {\r\n lines.push(...this._wrap(line, lines.length));\r\n }\r\n\r\n const width = Math.max(...lines.map((line) => line.width));\r\n const height = this.lineHeight * lines.length;\r\n\r\n if (this.options.textAlign !== \"left\" || this.options.translate) {\r\n lines.forEach((line) => {\r\n const anchor = (() => {\r\n switch (this.options.textAlign) {\r\n case \"right\":\r\n return width - line.width;\r\n case \"center\":\r\n return (width - line.width) / 2;\r\n case \"left\":\r\n default:\r\n return 0;\r\n }\r\n })();\r\n const translate = this.options.translate?.multiplyByFloats(width, height);\r\n line.glyphs.forEach((glyph) => {\r\n glyph.x += anchor;\r\n if (translate) {\r\n glyph.x += translate.x;\r\n glyph.y += translate.y;\r\n }\r\n });\r\n });\r\n }\r\n\r\n const glyphs = lines.flatMap((line) => line.glyphs);\r\n\r\n return {\r\n paragraph: trimmed.join(\"\\n\"),\r\n lines,\r\n glyphs,\r\n width,\r\n height,\r\n };\r\n }\r\n\r\n private _breakLines(text: string) {\r\n return text.split(\"\\n\");\r\n }\r\n\r\n private _collapse(text: string) {\r\n return text.replace(/\\t/g, \" \".repeat(this.options.tabSize)).replace(/ +/g, \" \");\r\n }\r\n\r\n private _wrap(text: string, lineOffset = 0) {\r\n const lines = new Array<SdfTextLine>();\r\n\r\n let currentLine = lineOffset;\r\n let currentGlyphs = new Array<SdfGlyph>();\r\n let currentCursor = 0;\r\n let currentWidth = 0;\r\n let lastChar: BMFontChar | undefined;\r\n let start = 0;\r\n let end = start;\r\n\r\n const pushCurrentLine = () => {\r\n lines.push({\r\n text: text.slice(start, end),\r\n glyphs: currentGlyphs,\r\n start: start,\r\n end: end,\r\n width: currentWidth,\r\n });\r\n };\r\n\r\n while (end < text.length) {\r\n const i = end;\r\n const charCode = text.charCodeAt(i);\r\n const char = this.fontAsset._getChar(charCode);\r\n const charWidth = char.width;\r\n const kerning = lastChar ? this.fontAsset._getKerning(lastChar.id, char.id) : 0;\r\n\r\n currentCursor += kerning + char.xoffset;\r\n const newWidth = currentCursor + charWidth;\r\n const cursorProgress = char.xadvance + this.options.letterSpacing;\r\n const nextPosition = currentCursor + cursorProgress;\r\n\r\n const shouldBreak = nextPosition > this.options.maxWidth || newWidth > this.options.maxWidth;\r\n\r\n if (shouldBreak) {\r\n pushCurrentLine();\r\n\r\n currentLine++;\r\n lastChar = undefined;\r\n currentCursor = 0;\r\n currentWidth = 0;\r\n start = end;\r\n end = start + 1;\r\n currentGlyphs = [];\r\n }\r\n\r\n const x = currentCursor;\r\n const y = currentLine * this.lineHeight + char.yoffset;\r\n\r\n currentGlyphs.push({\r\n char,\r\n line: currentLine,\r\n position: currentGlyphs.length,\r\n x: x,\r\n y: y,\r\n });\r\n\r\n if (!shouldBreak) {\r\n lastChar = char;\r\n currentCursor = nextPosition;\r\n currentWidth = newWidth;\r\n end++;\r\n } else {\r\n currentCursor = cursorProgress;\r\n }\r\n }\r\n\r\n if (currentGlyphs.length > 0) {\r\n pushCurrentLine();\r\n }\r\n\r\n return lines;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"paragraph.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/sdf/paragraph.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable babylonjs/available */\r\n/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { FontAsset } from \"../fontAsset\";\r\nimport { DefaultParagraphOptions, type ParagraphOptions } from \"../paragraphOptions\";\r\nimport type { BMFontChar } from \"./bmFont\";\r\nimport type { SdfGlyph } from \"./glyph\";\r\nimport type { SdfTextLine } from \"./line\";\r\n\r\n/** @internal */\r\nexport class SdfTextParagraph {\r\n public readonly options: ParagraphOptions;\r\n\r\n get lineHeight() {\r\n return this.fontAsset._font.common.lineHeight * this.options.lineHeight;\r\n }\r\n\r\n readonly paragraph;\r\n readonly lines;\r\n readonly width;\r\n readonly height;\r\n readonly glyphs;\r\n\r\n constructor(\r\n public readonly text: string,\r\n public readonly fontAsset: FontAsset,\r\n options?: Partial<ParagraphOptions>\r\n ) {\r\n this.options = { ...DefaultParagraphOptions, ...options };\r\n\r\n const { paragraph, lines, glyphs, width, height } = this._computeMetrics(text);\r\n\r\n this.paragraph = paragraph;\r\n this.lines = lines;\r\n this.glyphs = glyphs;\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n private _computeMetrics(text: string) {\r\n const collapsed = this._collapse(text);\r\n const breaked = this._breakLines(collapsed);\r\n const trimmed = breaked.map((line) => line.trim());\r\n\r\n const lines: SdfTextLine[] = [];\r\n for (const line of trimmed) {\r\n lines.push(...this._wrap(line, lines.length));\r\n }\r\n\r\n const width = Math.max(...lines.map((line) => line.width));\r\n const height = this.lineHeight * lines.length;\r\n\r\n if (this.options.textAlign !== \"left\" || this.options.translate) {\r\n lines.forEach((line) => {\r\n const anchor = (() => {\r\n switch (this.options.textAlign) {\r\n case \"right\":\r\n return width - line.width;\r\n case \"center\":\r\n return (width - line.width) / 2;\r\n case \"left\":\r\n default:\r\n return 0;\r\n }\r\n })();\r\n\r\n const x = this.options.translate ? this.options.translate.x * width : 0;\r\n const y = this.options.translate ? this.options.translate.y * height : 0;\r\n for (const glyph of line.glyphs) {\r\n glyph.x += anchor;\r\n glyph.x += x;\r\n glyph.y += y;\r\n }\r\n });\r\n }\r\n\r\n const glyphs = lines.flatMap((line) => line.glyphs);\r\n\r\n return {\r\n paragraph: trimmed.join(\"\\n\"),\r\n lines,\r\n glyphs,\r\n width,\r\n height,\r\n };\r\n }\r\n\r\n private _breakLines(text: string) {\r\n return text.split(\"\\n\");\r\n }\r\n\r\n private _collapse(text: string) {\r\n return text.replace(/\\t/g, \" \".repeat(this.options.tabSize)).replace(/ +/g, \" \");\r\n }\r\n\r\n private _wrap(text: string, lineOffset = 0) {\r\n const lines = new Array<SdfTextLine>();\r\n\r\n let currentLine = lineOffset;\r\n let currentGlyphs = new Array<SdfGlyph>();\r\n let currentCursor = 0;\r\n let currentWidth = 0;\r\n let lastChar: BMFontChar | undefined;\r\n let start = 0;\r\n let end = start;\r\n\r\n const pushCurrentLine = () => {\r\n lines.push({\r\n text: text.slice(start, end),\r\n glyphs: currentGlyphs,\r\n start: start,\r\n end: end,\r\n width: currentWidth,\r\n });\r\n };\r\n\r\n while (end < text.length) {\r\n const i = end;\r\n const charCode = text.charCodeAt(i);\r\n const char = this.fontAsset._getChar(charCode);\r\n const charWidth = char.width;\r\n const kerning = lastChar ? this.fontAsset._getKerning(lastChar.id, char.id) : 0;\r\n\r\n currentCursor += kerning;\r\n const newWidth = currentCursor + charWidth;\r\n const cursorProgress = char.xadvance + this.options.letterSpacing;\r\n const nextPosition = currentCursor + cursorProgress;\r\n\r\n const shouldBreak = nextPosition > this.options.maxWidth || newWidth > this.options.maxWidth;\r\n\r\n if (shouldBreak) {\r\n pushCurrentLine();\r\n\r\n currentLine++;\r\n lastChar = undefined;\r\n currentCursor = 0;\r\n currentWidth = 0;\r\n start = end;\r\n end = start + 1;\r\n currentGlyphs = [];\r\n }\r\n\r\n const x = currentCursor;\r\n const y = currentLine * this.lineHeight;\r\n\r\n currentGlyphs.push({\r\n char,\r\n line: currentLine,\r\n position: currentGlyphs.length,\r\n x: x,\r\n y: y,\r\n });\r\n\r\n if (!shouldBreak) {\r\n lastChar = char;\r\n currentCursor = nextPosition;\r\n currentWidth = newWidth;\r\n end++;\r\n } else {\r\n currentCursor = cursorProgress;\r\n }\r\n }\r\n\r\n if (currentGlyphs.length > 0) {\r\n if (lastChar) {\r\n // currentWidth += lastChar.xadvance;\r\n }\r\n pushCurrentLine();\r\n }\r\n\r\n return lines;\r\n }\r\n}\r\n"]}
@@ -1,5 +1,5 @@
1
1
  /** @internal */
2
- export declare const msdfVertexShader: {
2
+ export declare const msdfPixelShader: {
3
3
  name: string;
4
4
  shader: string;
5
5
  };
@@ -0,0 +1,14 @@
1
+ // Do not edit.
2
+ import { ShaderStore } from "@babylonjs/core/Engines/shaderStore.js";
3
+ const name = "msdfPixelShader";
4
+ const shader = `#extension GL_OES_standard_derivatives : enable
5
+ precision highp float;uniform sampler2D fontAtlas;uniform vec4 uColor;uniform vec4 uStrokeColor;uniform float uStrokeInsetWidth;uniform float uStrokeOutsetWidth;uniform float thickness;varying vec2 atlasUV;float median(vec3 msdf) {return max(min(msdf.r,msdf.g),min(max(msdf.r,msdf.g),msdf.b));}
6
+ void main(void)
7
+ {vec3 s=texture2D(fontAtlas,atlasUV).rgb;float sigDist=median(s)-0.5+thickness;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);float sigDistOutset=sigDist+uStrokeOutsetWidth*0.5;float sigDistInset=sigDist-uStrokeInsetWidth*0.5;float outset=clamp(sigDistOutset/fwidth(sigDistOutset)+0.5,0.0,1.0);float inset=1.0-clamp(sigDistInset/fwidth(sigDistInset)+0.5,0.0,1.0);float border=outset*inset;vec4 filledFragColor=vec4(uColor.rgb,alpha*uColor.a);vec4 strokedFragColor=vec4(uStrokeColor.rgb,border*uStrokeColor.a);gl_FragColor=mix(filledFragColor,strokedFragColor,border);}`;
8
+ // Sideeffect
9
+ if (!ShaderStore.ShadersStore[name]) {
10
+ ShaderStore.ShadersStore[name] = shader;
11
+ }
12
+ /** @internal */
13
+ export const msdfPixelShader = { name, shader };
14
+ //# sourceMappingURL=msdf.fragment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf.fragment.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/shaders/msdf.fragment.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,+CAAiC;AAEvD,MAAM,IAAI,GAAG,iBAAiB,CAAC;AAC/B,MAAM,MAAM,GAAG;;;ikBAGkjB,CAAC;AAClkB,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAClC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `#extension GL_OES_standard_derivatives : enable\nprecision highp float;uniform sampler2D fontAtlas;uniform vec4 uColor;uniform vec4 uStrokeColor;uniform float uStrokeInsetWidth;uniform float uStrokeOutsetWidth;uniform float thickness;varying vec2 atlasUV;float median(vec3 msdf) {return max(min(msdf.r,msdf.g),min(max(msdf.r,msdf.g),msdf.b));}\nvoid main(void)\n{vec3 s=texture2D(fontAtlas,atlasUV).rgb;float sigDist=median(s)-0.5+thickness;float alpha=clamp(sigDist/fwidth(sigDist)+0.5,0.0,1.0);float sigDistOutset=sigDist+uStrokeOutsetWidth*0.5;float sigDistInset=sigDist-uStrokeInsetWidth*0.5;float outset=clamp(sigDistOutset/fwidth(sigDistOutset)+0.5,0.0,1.0);float inset=1.0-clamp(sigDistInset/fwidth(sigDistInset)+0.5,0.0,1.0);float border=outset*inset;vec4 filledFragColor=vec4(uColor.rgb,alpha*uColor.a);vec4 strokedFragColor=vec4(uStrokeColor.rgb,border*uStrokeColor.a);gl_FragColor=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShader = { name, shader };\n"]}
@@ -0,0 +1,17 @@
1
+ // Do not edit.
2
+ import { ShaderStore } from "@babylonjs/core/Engines/shaderStore.js";
3
+ const name = "msdfVertexShader";
4
+ const shader = `#define BILLBOARD 1
5
+ #define BILLBOARDSCREENPROJECTED 2
6
+ attribute vec2 offsets;attribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;attribute vec4 uvs;uniform mat4 transform;uniform mat4 parentWorld;uniform mat4 view;uniform mat4 projection;uniform vec3 center;uniform int mode;varying vec2 atlasUV;void main(void) {mat4 world=mat4(world0,world1,world2,world3);vec4 worldPos=transform*(world*vec4(offsets.xy-vec2(0.5,0.5),0.,1.0));if (mode>=BILLBOARD) {vec3 viewPos=(view*parentWorld*vec4(0.,0.,0.,1.0)).xyz;
7
+ if (mode==BILLBOARDSCREENPROJECTED) {viewPos.x/=viewPos.z;viewPos.y/=viewPos.z;viewPos.z=1.0;}
8
+ gl_Position=projection*vec4(viewPos+worldPos.xyz,1.0); } else {vec3 viewPos=(view*parentWorld*worldPos).xyz;
9
+ gl_Position=projection*vec4(viewPos,1.0); }
10
+ atlasUV=vec2(uvs.x+offsets.x*uvs.z,uvs.y+(1.0-offsets.y)*uvs.w);}`;
11
+ // Sideeffect
12
+ if (!ShaderStore.ShadersStore[name]) {
13
+ ShaderStore.ShadersStore[name] = shader;
14
+ }
15
+ /** @internal */
16
+ export const msdfVertexShader = { name, shader };
17
+ //# sourceMappingURL=msdf.vertex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf.vertex.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/shaders/msdf.vertex.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,+CAAiC;AAEvD,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAChC,MAAM,MAAM,GAAG;;;;;;kEAMmD,CAAC;AACnE,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;IAClC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC5C,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute vec2 offsets;attribute vec4 world0;attribute vec4 world1;attribute vec4 world2;attribute vec4 world3;attribute vec4 uvs;uniform mat4 transform;uniform mat4 parentWorld;uniform mat4 view;uniform mat4 projection;uniform vec3 center;uniform int mode;varying vec2 atlasUV;void main(void) {mat4 world=mat4(world0,world1,world2,world3);vec4 worldPos=transform*(world*vec4(offsets.xy-vec2(0.5,0.5),0.,1.0));if (mode>=BILLBOARD) {vec3 viewPos=(view*parentWorld*vec4(0.,0.,0.,1.0)).xyz; \nif (mode==BILLBOARDSCREENPROJECTED) {viewPos.x/=viewPos.z;viewPos.y/=viewPos.z;viewPos.z=1.0;}\ngl_Position=projection*vec4(viewPos+worldPos.xyz,1.0); } else {vec3 viewPos=(view*parentWorld*worldPos).xyz; \ngl_Position=projection*vec4(viewPos,1.0); }\natlasUV=vec2(uvs.x+offsets.x*uvs.z,uvs.y+(1.0-offsets.y)*uvs.w);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStore[name]) {\n ShaderStore.ShadersStore[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShader = { name, shader };\n"]}
@@ -1,5 +1,5 @@
1
1
  /** @internal */
2
- export declare const msdfFragmentShader: {
2
+ export declare const msdfPixelShaderWGSL: {
3
3
  name: string;
4
4
  shader: string;
5
5
  };
@@ -0,0 +1,13 @@
1
+ // Do not edit.
2
+ import { ShaderStore } from "@babylonjs/core/Engines/shaderStore.js";
3
+ const name = "msdfPixelShader";
4
+ const shader = `var fontAtlas: texture_2d<f32>;var fontAtlasSampler: sampler;uniform uColor: vec4f;uniform thickness: f32;uniform uStrokeColor: vec4f;uniform uStrokeInsetWidth: f32;uniform uStrokeOutsetWidth: f32;varying atlasUV: vec2f;fn median(msdf: vec3<f32>)->f32 {let a=min(msdf.r,msdf.g);let b=max(msdf.r,msdf.g);return max(a,min(b,msdf.b));}
5
+ @fragment
6
+ fn main(input: FragmentInputs)->FragmentOutputs {let s=textureSample(fontAtlas,fontAtlasSampler,input.atlasUV).rgb;let sigDist=median(s)-0.5+uniforms.thickness;let afwidth=length(vec2<f32>(dpdx(sigDist),dpdy(sigDist)));let alpha=clamp(sigDist/afwidth+0.5,0.0,1.0);let sigDistOutset=sigDist+uniforms.uStrokeOutsetWidth*0.5;let sigDistInset=sigDist-uniforms.uStrokeInsetWidth*0.5;let afwidthOutset=length(vec2<f32>(dpdx(sigDistOutset),dpdy(sigDistOutset)));let afwidthInset=length(vec2<f32>(dpdx(sigDistInset),dpdy(sigDistInset)));let outset=clamp(sigDistOutset/afwidthOutset+0.5,0.0,1.0);let inset=1.0-clamp(sigDistInset/afwidthInset+0.5,0.0,1.0);let border=outset*inset;let filledFragColor=vec4<f32>(uniforms.uColor.rgb,alpha*uniforms.uColor.a);let strokedFragColor=vec4<f32>(uniforms.uStrokeColor.rgb,border*uniforms.uStrokeColor.a);fragmentOutputs.color=mix(filledFragColor,strokedFragColor,border);}`;
7
+ // Sideeffect
8
+ if (!ShaderStore.ShadersStoreWGSL[name]) {
9
+ ShaderStore.ShadersStoreWGSL[name] = shader;
10
+ }
11
+ /** @internal */
12
+ export const msdfPixelShaderWGSL = { name, shader };
13
+ //# sourceMappingURL=msdf.fragment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf.fragment.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/shadersWGSL/msdf.fragment.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,+CAAiC;AAEvD,MAAM,IAAI,GAAG,iBAAiB,CAAC;AAC/B,MAAM,MAAM,GAAG;;u4BAEw3B,CAAC;AACx4B,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfPixelShader\";\nconst shader = `var fontAtlas: texture_2d<f32>;var fontAtlasSampler: sampler;uniform uColor: vec4f;uniform thickness: f32;uniform uStrokeColor: vec4f;uniform uStrokeInsetWidth: f32;uniform uStrokeOutsetWidth: f32;varying atlasUV: vec2f;fn median(msdf: vec3<f32>)->f32 {let a=min(msdf.r,msdf.g);let b=max(msdf.r,msdf.g);return max(a,min(b,msdf.b));}\n@fragment\nfn main(input: FragmentInputs)->FragmentOutputs {let s=textureSample(fontAtlas,fontAtlasSampler,input.atlasUV).rgb;let sigDist=median(s)-0.5+uniforms.thickness;let afwidth=length(vec2<f32>(dpdx(sigDist),dpdy(sigDist)));let alpha=clamp(sigDist/afwidth+0.5,0.0,1.0);let sigDistOutset=sigDist+uniforms.uStrokeOutsetWidth*0.5;let sigDistInset=sigDist-uniforms.uStrokeInsetWidth*0.5;let afwidthOutset=length(vec2<f32>(dpdx(sigDistOutset),dpdy(sigDistOutset)));let afwidthInset=length(vec2<f32>(dpdx(sigDistInset),dpdy(sigDistInset)));let outset=clamp(sigDistOutset/afwidthOutset+0.5,0.0,1.0);let inset=1.0-clamp(sigDistInset/afwidthInset+0.5,0.0,1.0);let border=outset*inset;let filledFragColor=vec4<f32>(uniforms.uColor.rgb,alpha*uniforms.uColor.a);let strokedFragColor=vec4<f32>(uniforms.uStrokeColor.rgb,border*uniforms.uStrokeColor.a);fragmentOutputs.color=mix(filledFragColor,strokedFragColor,border);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfPixelShaderWGSL = { name, shader };\n"]}
@@ -1,5 +1,5 @@
1
1
  /** @internal */
2
- export declare const msdfFragmentShader: {
2
+ export declare const msdfVertexShaderWGSL: {
3
3
  name: string;
4
4
  shader: string;
5
5
  };
@@ -0,0 +1,21 @@
1
+ // Do not edit.
2
+ import { ShaderStore } from "@babylonjs/core/Engines/shaderStore.js";
3
+ const name = "msdfVertexShader";
4
+ const shader = `#define BILLBOARD 1
5
+ #define BILLBOARDSCREENPROJECTED 2
6
+ attribute offsets: vec2f;attribute world0: vec4f;attribute world1: vec4f;attribute world2: vec4f;attribute world3: vec4f;attribute uvs: vec4f;uniform transform: mat4x4f;uniform parentWorld: mat4x4f;uniform view: mat4x4f;uniform projection: mat4x4f;uniform mode: u32;varying atlasUV: vec2f;@vertex
7
+ fn main(input: VertexInputs)->FragmentInputs {let world=mat4x4<f32>(input.world0,input.world1,input.world2,input.world3);let localOffset=vec4<f32>(input.offsets-vec2<f32>(0.5,0.5),0.0,1.0);let worldPos=uniforms.transform*world*localOffset;if (uniforms.mode>=BILLBOARD) {
8
+ var viewPos=(uniforms.view*uniforms.parentWorld*vec4f(0.,0.,0.,1.0)).xyz;if (uniforms.mode==BILLBOARDSCREENPROJECTED) {viewPos=vec3f(viewPos.x/viewPos.z,viewPos.y/viewPos.z,1.0);}
9
+ vertexOutputs.position=uniforms.projection*vec4<f32>(viewPos+worldPos.xyz,1.0);} else {
10
+ let viewPos=(uniforms.view*uniforms.parentWorld*worldPos).xyz;vertexOutputs.position=uniforms.projection*vec4<f32>(viewPos,1.0);}
11
+ vertexOutputs.atlasUV=vec2<f32>(
12
+ input.uvs.x+input.offsets.x*input.uvs.z,
13
+ input.uvs.y+(1.0-input.offsets.y)*input.uvs.w
14
+ );}`;
15
+ // Sideeffect
16
+ if (!ShaderStore.ShadersStoreWGSL[name]) {
17
+ ShaderStore.ShadersStoreWGSL[name] = shader;
18
+ }
19
+ /** @internal */
20
+ export const msdfVertexShaderWGSL = { name, shader };
21
+ //# sourceMappingURL=msdf.vertex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf.vertex.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/shadersWGSL/msdf.vertex.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,+CAAiC;AAEvD,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAChC,MAAM,MAAM,GAAG;;;;;;;;;;IAUX,CAAC;AACL,aAAa;AACb,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IACtC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAChD,CAAC;AACD,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"msdfVertexShader\";\nconst shader = `#define BILLBOARD 1\n#define BILLBOARDSCREENPROJECTED 2\nattribute offsets: vec2f;attribute world0: vec4f;attribute world1: vec4f;attribute world2: vec4f;attribute world3: vec4f;attribute uvs: vec4f;uniform transform: mat4x4f;uniform parentWorld: mat4x4f;uniform view: mat4x4f;uniform projection: mat4x4f;uniform mode: u32;varying atlasUV: vec2f;@vertex\nfn main(input: VertexInputs)->FragmentInputs {let world=mat4x4<f32>(input.world0,input.world1,input.world2,input.world3);let localOffset=vec4<f32>(input.offsets-vec2<f32>(0.5,0.5),0.0,1.0);let worldPos=uniforms.transform*world*localOffset;if (uniforms.mode>=BILLBOARD) { \nvar viewPos=(uniforms.view*uniforms.parentWorld*vec4f(0.,0.,0.,1.0)).xyz;if (uniforms.mode==BILLBOARDSCREENPROJECTED) {viewPos=vec3f(viewPos.x/viewPos.z,viewPos.y/viewPos.z,1.0);} \nvertexOutputs.position=uniforms.projection*vec4<f32>(viewPos+worldPos.xyz,1.0);} else { \nlet viewPos=(uniforms.view*uniforms.parentWorld*worldPos).xyz;vertexOutputs.position=uniforms.projection*vec4<f32>(viewPos,1.0);}\nvertexOutputs.atlasUV=vec2<f32>(\ninput.uvs.x+input.offsets.x*input.uvs.z,\ninput.uvs.y+(1.0-input.offsets.y)*input.uvs.w\n);}`;\n// Sideeffect\nif (!ShaderStore.ShadersStoreWGSL[name]) {\n ShaderStore.ShadersStoreWGSL[name] = shader;\n}\n/** @internal */\nexport const msdfVertexShaderWGSL = { name, shader };\n"]}
@@ -3,13 +3,12 @@ import type { IDisposable } from "@babylonjs/core/scene.js";
3
3
  import type { Nullable } from "@babylonjs/core/types.js";
4
4
  import type { FontAsset } from "./fontAsset.js";
5
5
  import type { ParagraphOptions } from "./paragraphOptions.js";
6
- import { ThinMatrix } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.js";
7
- import type { IColor4Like, IMatrixLike } from "@babylonjs/core/Maths.js";
6
+ import type { IColor4Like, IMatrixLike } from "@babylonjs/core/Maths/math.like.js";
8
7
  /**
9
8
  * Abstract Node class from Babylon.js
10
9
  */
11
10
  export interface INodeLike {
12
- getWorldMatrix(): ThinMatrix;
11
+ getWorldMatrix(): IMatrixLike;
13
12
  }
14
13
  /**
15
14
  * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique
@@ -19,6 +18,7 @@ export interface INodeLike {
19
18
  * With metrics: #6RLCWP#35
20
19
  * Thickness: #IABMEZ#3
21
20
  * Solar system: #9YCDYC#9
21
+ * Stroke: #6RLCWP#37
22
22
  */
23
23
  export declare class TextRenderer implements IDisposable {
24
24
  private readonly _useVAO;
@@ -45,11 +45,22 @@ export declare class TextRenderer implements IDisposable {
45
45
  private _finalMatrix;
46
46
  private _lineMatrix;
47
47
  private _parentWorldMatrix;
48
- private _storedTranslation;
49
48
  /**
50
49
  * Gets or sets the color of the text
51
50
  */
52
51
  color: IColor4Like;
52
+ /**
53
+ * Gets or sets the color of the stroke around the text
54
+ */
55
+ strokeColor: IColor4Like;
56
+ /**
57
+ * Gets or sets the width of the stroke around the text (inset)
58
+ */
59
+ strokeInsetWidth: number;
60
+ /**
61
+ * Gets or sets the width of the stroke around the text (outset)
62
+ */
63
+ strokeOutsetWidth: number;
53
64
  /**
54
65
  * Gets or sets the thickness of the text (0 means as defined in the font)
55
66
  * Value must be between -0.5 and 0.5
@@ -61,14 +72,32 @@ export declare class TextRenderer implements IDisposable {
61
72
  */
62
73
  get parent(): Nullable<INodeLike>;
63
74
  set parent(value: Nullable<INodeLike>);
75
+ private _transformMatrix;
76
+ /**
77
+ * Gets or sets the transform matrix of the text renderer
78
+ * It will be applied in that order:
79
+ * parent x transform x paragraph world
80
+ */
81
+ get transformMatrix(): IMatrixLike;
82
+ set transformMatrix(value: IMatrixLike);
64
83
  /**
65
84
  * Gets or sets if the text is billboarded
66
85
  */
67
86
  isBillboard: boolean;
87
+ /**
88
+ * Gets or sets if the text is screen projected
89
+ * This will work only if the text is billboarded
90
+ */
91
+ isBillboardScreenProjected: boolean;
68
92
  /**
69
93
  * Gets the number of characters in the text renderer
70
94
  */
71
95
  get characterCount(): number;
96
+ /**
97
+ * Gets or sets if the text renderer should ignore the depth buffer
98
+ * Default is false
99
+ */
100
+ ignoreDepthBuffer: boolean;
72
101
  private constructor();
73
102
  private _resizeBuffers;
74
103
  private _setShaders;
@@ -3,7 +3,7 @@ import { Constants } from "@babylonjs/core/Engines/constants.js";
3
3
  import { DrawWrapper } from "@babylonjs/core/Materials/drawWrapper.js";
4
4
  import { SdfTextParagraph } from "./sdf/paragraph.js";
5
5
  import { ThinMatrix } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.js";
6
- import { CopyMatrixToArray, CopyMatrixToRef, IdentityMatrixToRef, InvertMatrixToRef, MultiplyMatricesToRef, ScalingMatrixToRef, TranslationMatrixToRef, } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.functions.js";
6
+ import { CopyMatrixToArray, CopyMatrixToRef, IdentityMatrixToRef, MultiplyMatricesToRef, ScalingMatrixToRef, TranslationMatrixToRef, } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.functions.js";
7
7
  /**
8
8
  * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique
9
9
  * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js
@@ -12,6 +12,7 @@ import { CopyMatrixToArray, CopyMatrixToRef, IdentityMatrixToRef, InvertMatrixTo
12
12
  * With metrics: #6RLCWP#35
13
13
  * Thickness: #IABMEZ#3
14
14
  * Solar system: #9YCDYC#9
15
+ * Stroke: #6RLCWP#37
15
16
  */
16
17
  export class TextRenderer {
17
18
  /**
@@ -23,6 +24,17 @@ export class TextRenderer {
23
24
  set parent(value) {
24
25
  this._parent = value;
25
26
  }
27
+ /**
28
+ * Gets or sets the transform matrix of the text renderer
29
+ * It will be applied in that order:
30
+ * parent x transform x paragraph world
31
+ */
32
+ get transformMatrix() {
33
+ return this._transformMatrix;
34
+ }
35
+ set transformMatrix(value) {
36
+ this._transformMatrix = value;
37
+ }
26
38
  /**
27
39
  * Gets the number of characters in the text renderer
28
40
  */
@@ -47,21 +59,43 @@ export class TextRenderer {
47
59
  this._finalMatrix = new ThinMatrix();
48
60
  this._lineMatrix = new ThinMatrix();
49
61
  this._parentWorldMatrix = new ThinMatrix();
50
- this._storedTranslation = { x: 0, y: 0, z: 0 };
51
62
  /**
52
63
  * Gets or sets the color of the text
53
64
  */
54
65
  this.color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
66
+ /**
67
+ * Gets or sets the color of the stroke around the text
68
+ */
69
+ this.strokeColor = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
70
+ /**
71
+ * Gets or sets the width of the stroke around the text (inset)
72
+ */
73
+ this.strokeInsetWidth = 0;
74
+ /**
75
+ * Gets or sets the width of the stroke around the text (outset)
76
+ */
77
+ this.strokeOutsetWidth = 0;
55
78
  /**
56
79
  * Gets or sets the thickness of the text (0 means as defined in the font)
57
80
  * Value must be between -0.5 and 0.5
58
81
  */
59
82
  this.thicknessControl = 0;
60
83
  this._parent = null;
84
+ this._transformMatrix = new ThinMatrix();
61
85
  /**
62
86
  * Gets or sets if the text is billboarded
63
87
  */
64
88
  this.isBillboard = false;
89
+ /**
90
+ * Gets or sets if the text is screen projected
91
+ * This will work only if the text is billboarded
92
+ */
93
+ this.isBillboardScreenProjected = false;
94
+ /**
95
+ * Gets or sets if the text renderer should ignore the depth buffer
96
+ * Default is false
97
+ */
98
+ this.ignoreDepthBuffer = false;
65
99
  this._engine = engine;
66
100
  this._shaderLanguage = shaderLanguage;
67
101
  this._font = font;
@@ -101,7 +135,7 @@ export class TextRenderer {
101
135
  this._drawWrapperBase.effect = this._engine.createEffect({
102
136
  vertexSource: vertex,
103
137
  fragmentSource: fragment,
104
- }, ["offsets", "world0", "world1", "world2", "world3", "uvs"], ["parentWorld", "view", "projection", "uColor", "unitRange", "texelSize", "thickness"], ["fontAtlas"], defines, undefined, undefined, undefined, undefined, this._shaderLanguage);
138
+ }, ["offsets", "world0", "world1", "world2", "world3", "uvs"], ["parentWorld", "view", "projection", "uColor", "thickness", "uStrokeColor", "uStrokeInsetWidth", "uStrokeOutsetWidth", "mode", "transform"], ["fontAtlas"], defines, undefined, undefined, undefined, undefined, this._shaderLanguage);
105
139
  this._drawWrapperBase.effect._refCount++;
106
140
  }
107
141
  /**
@@ -132,8 +166,8 @@ export class TextRenderer {
132
166
  this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;
133
167
  this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;
134
168
  this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;
135
- const x = g.x;
136
- const y = -g.y;
169
+ const x = g.x + g.char.xoffset;
170
+ const y = 1.0 - (g.y + g.char.yoffset);
137
171
  ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);
138
172
  MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);
139
173
  TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);
@@ -160,53 +194,27 @@ export class TextRenderer {
160
194
  const engine = this._engine;
161
195
  engine.setState(false);
162
196
  engine.enableEffect(drawWrapper);
163
- if (this.isBillboard) {
164
- // We will only consider translation for parent to simplify computation
165
- // Save parent translation
166
- if (this._parent) {
167
- const pwm = this._parent.getWorldMatrix().asArray();
168
- this._storedTranslation.x = pwm[12];
169
- this._storedTranslation.y = pwm[13];
170
- this._storedTranslation.z = pwm[14];
171
- }
172
- else {
173
- this._storedTranslation.x = 0;
174
- this._storedTranslation.y = 0;
175
- this._storedTranslation.z = 0;
176
- }
177
- // Cancel camera rotation
178
- const baseM = this._baseMatrix.asArray();
179
- CopyMatrixToArray(viewMatrix, baseM);
180
- baseM[12] = 0;
181
- baseM[13] = 0;
182
- baseM[14] = 0;
183
- InvertMatrixToRef(this._baseMatrix, this._parentWorldMatrix);
184
- // Restore translation
185
- const pwm = this._parentWorldMatrix.asArray();
186
- pwm[12] = this._storedTranslation.x;
187
- pwm[13] = this._storedTranslation.y;
188
- pwm[14] = this._storedTranslation.z;
197
+ if (this.ignoreDepthBuffer) {
198
+ engine.setDepthBuffer(false);
199
+ }
200
+ if (this._parent) {
201
+ CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);
189
202
  }
190
203
  else {
191
- if (this._parent) {
192
- CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);
193
- }
194
- else {
195
- IdentityMatrixToRef(this._parentWorldMatrix);
196
- }
204
+ IdentityMatrixToRef(this._parentWorldMatrix);
197
205
  }
206
+ effect.setInt("mode", this.isBillboard ? (this.isBillboardScreenProjected ? 2 : 1) : 0);
198
207
  effect.setMatrix("parentWorld", this._parentWorldMatrix);
199
208
  effect.setMatrix("view", viewMatrix);
200
209
  effect.setMatrix("projection", projectionMatrix);
210
+ effect.setMatrix("transform", this.transformMatrix);
201
211
  // Texture
202
- const textureWidth = this._font._font.common.scaleW;
203
- const textureHeight = this._font._font.common.scaleW;
204
- const distanceRange = this._font._font.distanceField.distanceRange;
205
212
  effect.setTexture("fontAtlas", this._font.textures[0]);
206
- effect.setFloat2("unitRange", distanceRange / textureWidth, distanceRange / textureHeight);
207
- effect.setFloat2("texelSize", 1.0 / textureWidth, 1.0 / textureHeight);
208
213
  effect.setDirectColor4("uColor", this.color);
214
+ effect.setDirectColor4("uStrokeColor", this.strokeColor);
209
215
  effect.setFloat("thickness", this.thicknessControl * 0.9);
216
+ effect.setFloat("uStrokeInsetWidth", this.strokeInsetWidth);
217
+ effect.setFloat("uStrokeOutsetWidth", this.strokeOutsetWidth);
210
218
  const instanceCount = this._charMatrices.length / 16;
211
219
  // Need update?
212
220
  if (this._isDirty) {
@@ -230,6 +238,10 @@ export class TextRenderer {
230
238
  engine.setAlphaMode(Constants.ALPHA_COMBINE);
231
239
  engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);
232
240
  engine.unbindInstanceAttributes();
241
+ engine.setAlphaMode(Constants.ALPHA_DISABLE);
242
+ if (this.ignoreDepthBuffer) {
243
+ engine.setDepthBuffer(true);
244
+ }
233
245
  }
234
246
  /**
235
247
  * Release associated resources
@@ -267,12 +279,12 @@ export class TextRenderer {
267
279
  let fragment = "";
268
280
  if (engine.isWebGPU) {
269
281
  shaderLanguage = 1 /* ShaderLanguage.WGSL */;
270
- vertex = (await import("./webgpu/vertex.js")).msdfVertexShader.shader;
271
- fragment = (await import("./webgpu/fragment.js")).msdfFragmentShader.shader;
282
+ vertex = (await import("./shadersWGSL/msdf.vertex.js")).msdfVertexShaderWGSL.shader;
283
+ fragment = (await import("./shadersWGSL/msdf.fragment.js")).msdfPixelShaderWGSL.shader;
272
284
  }
273
285
  else {
274
- vertex = (await import("./webgl/vertex.js")).msdfVertexShader.shader;
275
- fragment = (await import("./webgl/fragment.js")).msdfFragmentShader.shader;
286
+ vertex = (await import("./shaders/msdf.vertex.js")).msdfVertexShader.shader;
287
+ fragment = (await import("./shaders/msdf.fragment.js")).msdfPixelShader.shader;
276
288
  }
277
289
  const textRenderer = new TextRenderer(engine, shaderLanguage, font);
278
290
  textRenderer._setShaders(vertex, fragment);
@@ -1 +1 @@
1
- {"version":3,"file":"textRenderer.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/textRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Buffer } from \"core/Buffers/buffer\";\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport { DrawWrapper } from \"core/Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport type { IDisposable } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { SdfTextParagraph } from \"./sdf/paragraph\";\r\nimport type { FontAsset } from \"./fontAsset\";\r\nimport type { ParagraphOptions } from \"./paragraphOptions\";\r\nimport { ThinMatrix } from \"core/Maths/ThinMaths/thinMath.matrix\";\r\nimport {\r\n CopyMatrixToArray,\r\n CopyMatrixToRef,\r\n IdentityMatrixToRef,\r\n InvertMatrixToRef,\r\n MultiplyMatricesToRef,\r\n ScalingMatrixToRef,\r\n TranslationMatrixToRef,\r\n} from \"core/Maths/ThinMaths/thinMath.matrix.functions\";\r\nimport type { IColor4Like, IMatrixLike, IVector3Like } from \"core/Maths\";\r\n\r\n/**\r\n * Abstract Node class from Babylon.js\r\n */\r\nexport interface INodeLike {\r\n getWorldMatrix(): ThinMatrix;\r\n}\r\n\r\n/**\r\n * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique\r\n * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js\r\n * #6RLCWP#16\r\n * Star wars scroller: #6RLCWP#29\r\n * With metrics: #6RLCWP#35\r\n * Thickness: #IABMEZ#3\r\n * Solar system: #9YCDYC#9\r\n */\r\nexport class TextRenderer implements IDisposable {\r\n private readonly _useVAO: boolean = false;\r\n private _engine: AbstractEngine;\r\n private _shaderLanguage: ShaderLanguage;\r\n private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n private _spriteBuffer: Nullable<Buffer>;\r\n private _worldBuffer: Nullable<Buffer>;\r\n private _uvBuffer: Nullable<Buffer>;\r\n private _drawWrapperBase: DrawWrapper;\r\n private _vertexArrayObject: WebGLVertexArrayObject;\r\n private _font: FontAsset;\r\n private _charMatrices = new Array<number>();\r\n private _charUvs = new Array<number>();\r\n private _isDirty = true;\r\n private _baseLine = 0;\r\n\r\n // Cache\r\n private _scalingMatrix = new ThinMatrix();\r\n private _fontScaleMatrix = new ThinMatrix();\r\n private _offsetMatrix = new ThinMatrix();\r\n private _translationMatrix = new ThinMatrix();\r\n private _baseMatrix = new ThinMatrix();\r\n private _scaledMatrix = new ThinMatrix();\r\n private _localMatrix = new ThinMatrix();\r\n private _finalMatrix = new ThinMatrix();\r\n private _lineMatrix = new ThinMatrix();\r\n private _parentWorldMatrix = new ThinMatrix();\r\n private _storedTranslation: IVector3Like = { x: 0, y: 0, z: 0 };\r\n\r\n /**\r\n * Gets or sets the color of the text\r\n */\r\n public color: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the thickness of the text (0 means as defined in the font)\r\n * Value must be between -0.5 and 0.5\r\n */\r\n public thicknessControl = 0;\r\n\r\n private _parent: Nullable<INodeLike> = null;\r\n\r\n /**\r\n * Gets or sets the parent of the text renderer\r\n */\r\n public get parent(): Nullable<INodeLike> {\r\n return this._parent;\r\n }\r\n\r\n public set parent(value: Nullable<INodeLike>) {\r\n this._parent = value;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text is billboarded\r\n */\r\n public isBillboard = false;\r\n\r\n /**\r\n * Gets the number of characters in the text renderer\r\n */\r\n public get characterCount(): number {\r\n return this._charMatrices.length / 16;\r\n }\r\n\r\n private constructor(engine: AbstractEngine, shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL, font: FontAsset) {\r\n this._engine = engine;\r\n this._shaderLanguage = shaderLanguage;\r\n this._font = font;\r\n this._baseLine = font._font.common.lineHeight * font.scale;\r\n\r\n this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;\r\n\r\n // Main vertex buffer\r\n const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\r\n this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n this._vertexBuffers[\"offsets\"] = this._spriteBuffer.createVertexBuffer(\"offsets\", 0, 2);\r\n\r\n // Instances\r\n this._resizeBuffers(128);\r\n }\r\n\r\n private _resizeBuffers(capacity: number) {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n this._worldBuffer = new Buffer(this._engine, new Float32Array(capacity * 16), true, 16);\r\n this._vertexBuffers[\"world0\"] = this._worldBuffer.createVertexBuffer(\"world0\", 0, 4, 16, true);\r\n this._vertexBuffers[\"world1\"] = this._worldBuffer.createVertexBuffer(\"world1\", 4, 4, 16, true);\r\n this._vertexBuffers[\"world2\"] = this._worldBuffer.createVertexBuffer(\"world2\", 8, 4, 16, true);\r\n this._vertexBuffers[\"world3\"] = this._worldBuffer.createVertexBuffer(\"world3\", 12, 4, 16, true);\r\n\r\n this._uvBuffer = new Buffer(this._engine, new Float32Array(capacity * 4), true, 4);\r\n this._vertexBuffers[\"uvs\"] = this._uvBuffer.createVertexBuffer(\"uvs\", 0, 4, 4, true);\r\n }\r\n\r\n private _setShaders(vertex: string, fragment: string) {\r\n this._drawWrapperBase?.dispose();\r\n\r\n this._drawWrapperBase = new DrawWrapper(this._engine);\r\n\r\n if (this._drawWrapperBase.drawContext) {\r\n this._drawWrapperBase.drawContext.useInstancing = true;\r\n }\r\n\r\n const defines = \"\";\r\n\r\n this._drawWrapperBase.effect = this._engine.createEffect(\r\n {\r\n vertexSource: vertex,\r\n fragmentSource: fragment,\r\n },\r\n [\"offsets\", \"world0\", \"world1\", \"world2\", \"world3\", \"uvs\"],\r\n [\"parentWorld\", \"view\", \"projection\", \"uColor\", \"unitRange\", \"texelSize\", \"thickness\"],\r\n [\"fontAtlas\"],\r\n defines,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n this._shaderLanguage\r\n );\r\n\r\n this._drawWrapperBase.effect._refCount++;\r\n }\r\n\r\n /**\r\n * Add a paragraph of text to the renderer\r\n * @param text define the text to add\r\n * @param options define the options to use for the paragraph (optional)\r\n * @param worldMatrix define the world matrix to use for the paragraph (optional)\r\n */\r\n public addParagraph(text: string, options?: Partial<ParagraphOptions>, worldMatrix?: IMatrixLike) {\r\n const paragraph = new SdfTextParagraph(text, this._font, options);\r\n\r\n const fontScale = this._font.scale;\r\n\r\n const texWidth = this._font._font.common.scaleW;\r\n const texHeight = this._font._font.common.scaleH;\r\n const glyphs = paragraph.glyphs.filter((g) => g.char.page >= 0);\r\n\r\n let worldMatrixToUse = worldMatrix;\r\n\r\n if (!worldMatrixToUse) {\r\n const lineHeight = paragraph.lineHeight * fontScale;\r\n const lineOffset = (paragraph.lines.length * lineHeight) / 2;\r\n TranslationMatrixToRef(0, this._baseLine - lineOffset, 0, this._lineMatrix);\r\n worldMatrixToUse = this._lineMatrix;\r\n }\r\n\r\n ScalingMatrixToRef(fontScale, fontScale, 1.0, this._fontScaleMatrix);\r\n TranslationMatrixToRef(0.5, -0.5, 0, this._offsetMatrix);\r\n\r\n const charsUvsBase = this._charUvs.length;\r\n const matricesBase = this._charMatrices.length;\r\n glyphs.forEach((g, i) => {\r\n this._charUvs[charsUvsBase + i * 4 + 0] = g.char.x / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;\r\n this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;\r\n\r\n const x = g.x;\r\n const y = -g.y;\r\n\r\n ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);\r\n MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);\r\n\r\n TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);\r\n MultiplyMatricesToRef(this._baseMatrix, this._fontScaleMatrix, this._scaledMatrix);\r\n MultiplyMatricesToRef(this._scaledMatrix, this._translationMatrix, this._localMatrix);\r\n\r\n MultiplyMatricesToRef(this._localMatrix, worldMatrixToUse, this._finalMatrix);\r\n CopyMatrixToArray(this._finalMatrix, this._charMatrices, matricesBase + i * 16);\r\n });\r\n\r\n this._isDirty = true;\r\n\r\n this._baseLine -= paragraph.lineHeight * fontScale * paragraph.lines.length;\r\n }\r\n\r\n /**\r\n * Render the text using the provided view and projection matrices\r\n * @param viewMatrix define the view matrix to use\r\n * @param projectionMatrix define the projection matrix to use\r\n */\r\n public render(viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike): void {\r\n const drawWrapper = this._drawWrapperBase;\r\n\r\n const effect = drawWrapper.effect!;\r\n\r\n // Check\r\n if (!effect.isReady()) {\r\n return;\r\n }\r\n const engine = this._engine;\r\n\r\n engine.setState(false);\r\n engine.enableEffect(drawWrapper);\r\n\r\n if (this.isBillboard) {\r\n // We will only consider translation for parent to simplify computation\r\n // Save parent translation\r\n if (this._parent) {\r\n const pwm = this._parent.getWorldMatrix().asArray();\r\n this._storedTranslation.x = pwm[12];\r\n this._storedTranslation.y = pwm[13];\r\n this._storedTranslation.z = pwm[14];\r\n } else {\r\n this._storedTranslation.x = 0;\r\n this._storedTranslation.y = 0;\r\n this._storedTranslation.z = 0;\r\n }\r\n // Cancel camera rotation\r\n const baseM = this._baseMatrix.asArray();\r\n CopyMatrixToArray(viewMatrix, baseM);\r\n baseM[12] = 0;\r\n baseM[13] = 0;\r\n baseM[14] = 0;\r\n InvertMatrixToRef(this._baseMatrix, this._parentWorldMatrix);\r\n\r\n // Restore translation\r\n const pwm = this._parentWorldMatrix.asArray();\r\n pwm[12] = this._storedTranslation.x;\r\n pwm[13] = this._storedTranslation.y;\r\n pwm[14] = this._storedTranslation.z;\r\n } else {\r\n if (this._parent) {\r\n CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);\r\n } else {\r\n IdentityMatrixToRef(this._parentWorldMatrix);\r\n }\r\n }\r\n\r\n effect.setMatrix(\"parentWorld\", this._parentWorldMatrix);\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n\r\n // Texture\r\n const textureWidth = this._font._font.common.scaleW;\r\n const textureHeight = this._font._font.common.scaleW;\r\n const distanceRange = this._font._font.distanceField.distanceRange;\r\n\r\n effect.setTexture(\"fontAtlas\", this._font.textures[0]);\r\n effect.setFloat2(\"unitRange\", distanceRange / textureWidth, distanceRange / textureHeight);\r\n effect.setFloat2(\"texelSize\", 1.0 / textureWidth, 1.0 / textureHeight);\r\n effect.setDirectColor4(\"uColor\", this.color);\r\n effect.setFloat(\"thickness\", this.thicknessControl * 0.9);\r\n\r\n const instanceCount = this._charMatrices.length / 16;\r\n\r\n // Need update?\r\n if (this._isDirty) {\r\n this._isDirty = false;\r\n\r\n if (this._worldBuffer!.getBuffer()!.capacity / 4 < instanceCount * 16) {\r\n this._resizeBuffers(instanceCount);\r\n }\r\n\r\n this._worldBuffer!.update(this._charMatrices);\r\n this._uvBuffer!.update(this._charUvs);\r\n }\r\n\r\n if (this._useVAO) {\r\n if (!this._vertexArrayObject) {\r\n this._vertexArrayObject = (engine as ThinEngine).recordVertexArrayObject(this._vertexBuffers, null, effect);\r\n }\r\n (engine as ThinEngine).bindVertexArrayObject(this._vertexArrayObject, null);\r\n } else {\r\n // VBOs\r\n engine.bindBuffers(this._vertexBuffers, null, effect);\r\n }\r\n\r\n engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n\r\n engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);\r\n\r\n engine.unbindInstanceAttributes();\r\n }\r\n\r\n /**\r\n * Release associated resources\r\n */\r\n public dispose(): void {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n if (this._spriteBuffer) {\r\n this._spriteBuffer.dispose();\r\n this._spriteBuffer = null;\r\n }\r\n\r\n if (this._vertexArrayObject) {\r\n (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n (<any>this._vertexArrayObject) = null;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new TextRenderer instance asynchronously\r\n * @param font define the font asset to use\r\n * @param engine define the engine to use\r\n * @returns a promise that resolves to the created TextRenderer instance\r\n */\r\n public static async CreateTextRendererAsync(font: FontAsset, engine: AbstractEngine) {\r\n if (!engine.getCaps().instancedArrays || !engine._features.supportSpriteInstancing) {\r\n throw new Error(\"Instanced arrays are required for MSDF text rendering.\");\r\n }\r\n\r\n let shaderLanguage = ShaderLanguage.GLSL;\r\n let vertex: string = \"\";\r\n let fragment: string = \"\";\r\n if (engine.isWebGPU) {\r\n shaderLanguage = ShaderLanguage.WGSL;\r\n vertex = (await import(\"./webgpu/vertex\")).msdfVertexShader.shader;\r\n fragment = (await import(\"./webgpu/fragment\")).msdfFragmentShader.shader;\r\n } else {\r\n vertex = (await import(\"./webgl/vertex\")).msdfVertexShader.shader;\r\n fragment = (await import(\"./webgl/fragment\")).msdfFragmentShader.shader;\r\n }\r\n\r\n const textRenderer = new TextRenderer(engine, shaderLanguage, font);\r\n textRenderer._setShaders(vertex, fragment);\r\n\r\n return textRenderer;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"textRenderer.js","sourceRoot":"","sources":["../../../../dev/addons/src/msdfText/textRenderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Buffer } from \"core/Buffers/buffer\";\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport { DrawWrapper } from \"core/Materials/drawWrapper\";\r\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\r\nimport type { IDisposable } from \"core/scene\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { SdfTextParagraph } from \"./sdf/paragraph\";\r\nimport type { FontAsset } from \"./fontAsset\";\r\nimport type { ParagraphOptions } from \"./paragraphOptions\";\r\nimport { ThinMatrix } from \"core/Maths/ThinMaths/thinMath.matrix\";\r\nimport {\r\n CopyMatrixToArray,\r\n CopyMatrixToRef,\r\n IdentityMatrixToRef,\r\n MultiplyMatricesToRef,\r\n ScalingMatrixToRef,\r\n TranslationMatrixToRef,\r\n} from \"core/Maths/ThinMaths/thinMath.matrix.functions\";\r\nimport type { IColor4Like, IMatrixLike } from \"core/Maths/math.like\";\r\n\r\n/**\r\n * Abstract Node class from Babylon.js\r\n */\r\nexport interface INodeLike {\r\n getWorldMatrix(): IMatrixLike;\r\n}\r\n\r\n/**\r\n * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique\r\n * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js\r\n * #6RLCWP#16\r\n * Star wars scroller: #6RLCWP#29\r\n * With metrics: #6RLCWP#35\r\n * Thickness: #IABMEZ#3\r\n * Solar system: #9YCDYC#9\r\n * Stroke: #6RLCWP#37\r\n */\r\nexport class TextRenderer implements IDisposable {\r\n private readonly _useVAO: boolean = false;\r\n private _engine: AbstractEngine;\r\n private _shaderLanguage: ShaderLanguage;\r\n private _vertexBuffers: { [key: string]: VertexBuffer } = {};\r\n private _spriteBuffer: Nullable<Buffer>;\r\n private _worldBuffer: Nullable<Buffer>;\r\n private _uvBuffer: Nullable<Buffer>;\r\n private _drawWrapperBase: DrawWrapper;\r\n private _vertexArrayObject: WebGLVertexArrayObject;\r\n private _font: FontAsset;\r\n private _charMatrices = new Array<number>();\r\n private _charUvs = new Array<number>();\r\n private _isDirty = true;\r\n private _baseLine = 0;\r\n\r\n // Cache\r\n private _scalingMatrix = new ThinMatrix();\r\n private _fontScaleMatrix = new ThinMatrix();\r\n private _offsetMatrix = new ThinMatrix();\r\n private _translationMatrix = new ThinMatrix();\r\n private _baseMatrix = new ThinMatrix();\r\n private _scaledMatrix = new ThinMatrix();\r\n private _localMatrix = new ThinMatrix();\r\n private _finalMatrix = new ThinMatrix();\r\n private _lineMatrix = new ThinMatrix();\r\n private _parentWorldMatrix = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the color of the text\r\n */\r\n public color: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the color of the stroke around the text\r\n */\r\n public strokeColor: IColor4Like = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (inset)\r\n */\r\n public strokeInsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the width of the stroke around the text (outset)\r\n */\r\n public strokeOutsetWidth = 0;\r\n\r\n /**\r\n * Gets or sets the thickness of the text (0 means as defined in the font)\r\n * Value must be between -0.5 and 0.5\r\n */\r\n public thicknessControl = 0;\r\n\r\n private _parent: Nullable<INodeLike> = null;\r\n\r\n /**\r\n * Gets or sets the parent of the text renderer\r\n */\r\n public get parent(): Nullable<INodeLike> {\r\n return this._parent;\r\n }\r\n\r\n public set parent(value: Nullable<INodeLike>) {\r\n this._parent = value;\r\n }\r\n\r\n private _transformMatrix: IMatrixLike = new ThinMatrix();\r\n\r\n /**\r\n * Gets or sets the transform matrix of the text renderer\r\n * It will be applied in that order:\r\n * parent x transform x paragraph world\r\n */\r\n public get transformMatrix(): IMatrixLike {\r\n return this._transformMatrix;\r\n }\r\n\r\n public set transformMatrix(value: IMatrixLike) {\r\n this._transformMatrix = value;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text is billboarded\r\n */\r\n public isBillboard = false;\r\n\r\n /**\r\n * Gets or sets if the text is screen projected\r\n * This will work only if the text is billboarded\r\n */\r\n public isBillboardScreenProjected = false;\r\n\r\n /**\r\n * Gets the number of characters in the text renderer\r\n */\r\n public get characterCount(): number {\r\n return this._charMatrices.length / 16;\r\n }\r\n\r\n /**\r\n * Gets or sets if the text renderer should ignore the depth buffer\r\n * Default is false\r\n */\r\n public ignoreDepthBuffer = false;\r\n\r\n private constructor(engine: AbstractEngine, shaderLanguage: ShaderLanguage = ShaderLanguage.GLSL, font: FontAsset) {\r\n this._engine = engine;\r\n this._shaderLanguage = shaderLanguage;\r\n this._font = font;\r\n this._baseLine = font._font.common.lineHeight * font.scale;\r\n\r\n this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;\r\n\r\n // Main vertex buffer\r\n const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\r\n this._spriteBuffer = new Buffer(engine, spriteData, false, 2);\r\n this._vertexBuffers[\"offsets\"] = this._spriteBuffer.createVertexBuffer(\"offsets\", 0, 2);\r\n\r\n // Instances\r\n this._resizeBuffers(128);\r\n }\r\n\r\n private _resizeBuffers(capacity: number) {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n this._worldBuffer = new Buffer(this._engine, new Float32Array(capacity * 16), true, 16);\r\n this._vertexBuffers[\"world0\"] = this._worldBuffer.createVertexBuffer(\"world0\", 0, 4, 16, true);\r\n this._vertexBuffers[\"world1\"] = this._worldBuffer.createVertexBuffer(\"world1\", 4, 4, 16, true);\r\n this._vertexBuffers[\"world2\"] = this._worldBuffer.createVertexBuffer(\"world2\", 8, 4, 16, true);\r\n this._vertexBuffers[\"world3\"] = this._worldBuffer.createVertexBuffer(\"world3\", 12, 4, 16, true);\r\n\r\n this._uvBuffer = new Buffer(this._engine, new Float32Array(capacity * 4), true, 4);\r\n this._vertexBuffers[\"uvs\"] = this._uvBuffer.createVertexBuffer(\"uvs\", 0, 4, 4, true);\r\n }\r\n\r\n private _setShaders(vertex: string, fragment: string) {\r\n this._drawWrapperBase?.dispose();\r\n\r\n this._drawWrapperBase = new DrawWrapper(this._engine);\r\n\r\n if (this._drawWrapperBase.drawContext) {\r\n this._drawWrapperBase.drawContext.useInstancing = true;\r\n }\r\n\r\n const defines = \"\";\r\n\r\n this._drawWrapperBase.effect = this._engine.createEffect(\r\n {\r\n vertexSource: vertex,\r\n fragmentSource: fragment,\r\n },\r\n [\"offsets\", \"world0\", \"world1\", \"world2\", \"world3\", \"uvs\"],\r\n [\"parentWorld\", \"view\", \"projection\", \"uColor\", \"thickness\", \"uStrokeColor\", \"uStrokeInsetWidth\", \"uStrokeOutsetWidth\", \"mode\", \"transform\"],\r\n [\"fontAtlas\"],\r\n defines,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n this._shaderLanguage\r\n );\r\n\r\n this._drawWrapperBase.effect._refCount++;\r\n }\r\n\r\n /**\r\n * Add a paragraph of text to the renderer\r\n * @param text define the text to add\r\n * @param options define the options to use for the paragraph (optional)\r\n * @param worldMatrix define the world matrix to use for the paragraph (optional)\r\n */\r\n public addParagraph(text: string, options?: Partial<ParagraphOptions>, worldMatrix?: IMatrixLike) {\r\n const paragraph = new SdfTextParagraph(text, this._font, options);\r\n\r\n const fontScale = this._font.scale;\r\n\r\n const texWidth = this._font._font.common.scaleW;\r\n const texHeight = this._font._font.common.scaleH;\r\n const glyphs = paragraph.glyphs.filter((g) => g.char.page >= 0);\r\n\r\n let worldMatrixToUse = worldMatrix;\r\n\r\n if (!worldMatrixToUse) {\r\n const lineHeight = paragraph.lineHeight * fontScale;\r\n const lineOffset = (paragraph.lines.length * lineHeight) / 2;\r\n TranslationMatrixToRef(0, this._baseLine - lineOffset, 0, this._lineMatrix);\r\n worldMatrixToUse = this._lineMatrix;\r\n }\r\n\r\n ScalingMatrixToRef(fontScale, fontScale, 1.0, this._fontScaleMatrix);\r\n TranslationMatrixToRef(0.5, -0.5, 0, this._offsetMatrix);\r\n\r\n const charsUvsBase = this._charUvs.length;\r\n const matricesBase = this._charMatrices.length;\r\n glyphs.forEach((g, i) => {\r\n this._charUvs[charsUvsBase + i * 4 + 0] = g.char.x / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;\r\n this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;\r\n this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;\r\n\r\n const x = g.x + g.char.xoffset;\r\n const y = 1.0 - (g.y + g.char.yoffset);\r\n\r\n ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);\r\n MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);\r\n\r\n TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);\r\n MultiplyMatricesToRef(this._baseMatrix, this._fontScaleMatrix, this._scaledMatrix);\r\n MultiplyMatricesToRef(this._scaledMatrix, this._translationMatrix, this._localMatrix);\r\n\r\n MultiplyMatricesToRef(this._localMatrix, worldMatrixToUse, this._finalMatrix);\r\n CopyMatrixToArray(this._finalMatrix, this._charMatrices, matricesBase + i * 16);\r\n });\r\n\r\n this._isDirty = true;\r\n\r\n this._baseLine -= paragraph.lineHeight * fontScale * paragraph.lines.length;\r\n }\r\n\r\n /**\r\n * Render the text using the provided view and projection matrices\r\n * @param viewMatrix define the view matrix to use\r\n * @param projectionMatrix define the projection matrix to use\r\n */\r\n public render(viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike): void {\r\n const drawWrapper = this._drawWrapperBase;\r\n\r\n const effect = drawWrapper.effect!;\r\n\r\n // Check\r\n if (!effect.isReady()) {\r\n return;\r\n }\r\n const engine = this._engine;\r\n\r\n engine.setState(false);\r\n engine.enableEffect(drawWrapper);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(false);\r\n }\r\n\r\n if (this._parent) {\r\n CopyMatrixToRef(this._parent.getWorldMatrix(), this._parentWorldMatrix);\r\n } else {\r\n IdentityMatrixToRef(this._parentWorldMatrix);\r\n }\r\n\r\n effect.setInt(\"mode\", this.isBillboard ? (this.isBillboardScreenProjected ? 2 : 1) : 0);\r\n effect.setMatrix(\"parentWorld\", this._parentWorldMatrix);\r\n effect.setMatrix(\"view\", viewMatrix);\r\n effect.setMatrix(\"projection\", projectionMatrix);\r\n effect.setMatrix(\"transform\", this.transformMatrix);\r\n\r\n // Texture\r\n effect.setTexture(\"fontAtlas\", this._font.textures[0]);\r\n effect.setDirectColor4(\"uColor\", this.color);\r\n effect.setDirectColor4(\"uStrokeColor\", this.strokeColor);\r\n effect.setFloat(\"thickness\", this.thicknessControl * 0.9);\r\n effect.setFloat(\"uStrokeInsetWidth\", this.strokeInsetWidth);\r\n effect.setFloat(\"uStrokeOutsetWidth\", this.strokeOutsetWidth);\r\n\r\n const instanceCount = this._charMatrices.length / 16;\r\n\r\n // Need update?\r\n if (this._isDirty) {\r\n this._isDirty = false;\r\n\r\n if (this._worldBuffer!.getBuffer()!.capacity / 4 < instanceCount * 16) {\r\n this._resizeBuffers(instanceCount);\r\n }\r\n\r\n this._worldBuffer!.update(this._charMatrices);\r\n this._uvBuffer!.update(this._charUvs);\r\n }\r\n\r\n if (this._useVAO) {\r\n if (!this._vertexArrayObject) {\r\n this._vertexArrayObject = (engine as ThinEngine).recordVertexArrayObject(this._vertexBuffers, null, effect);\r\n }\r\n (engine as ThinEngine).bindVertexArrayObject(this._vertexArrayObject, null);\r\n } else {\r\n // VBOs\r\n engine.bindBuffers(this._vertexBuffers, null, effect);\r\n }\r\n\r\n engine.setAlphaMode(Constants.ALPHA_COMBINE);\r\n engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);\r\n engine.unbindInstanceAttributes();\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n\r\n if (this.ignoreDepthBuffer) {\r\n engine.setDepthBuffer(true);\r\n }\r\n }\r\n\r\n /**\r\n * Release associated resources\r\n */\r\n public dispose(): void {\r\n if (this._worldBuffer) {\r\n this._worldBuffer.dispose();\r\n this._worldBuffer = null;\r\n }\r\n\r\n if (this._uvBuffer) {\r\n this._uvBuffer.dispose();\r\n this._uvBuffer = null;\r\n }\r\n\r\n if (this._spriteBuffer) {\r\n this._spriteBuffer.dispose();\r\n this._spriteBuffer = null;\r\n }\r\n\r\n if (this._vertexArrayObject) {\r\n (this._engine as ThinEngine).releaseVertexArrayObject(this._vertexArrayObject);\r\n (<any>this._vertexArrayObject) = null;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new TextRenderer instance asynchronously\r\n * @param font define the font asset to use\r\n * @param engine define the engine to use\r\n * @returns a promise that resolves to the created TextRenderer instance\r\n */\r\n public static async CreateTextRendererAsync(font: FontAsset, engine: AbstractEngine) {\r\n if (!engine.getCaps().instancedArrays || !engine._features.supportSpriteInstancing) {\r\n throw new Error(\"Instanced arrays are required for MSDF text rendering.\");\r\n }\r\n\r\n let shaderLanguage = ShaderLanguage.GLSL;\r\n let vertex: string = \"\";\r\n let fragment: string = \"\";\r\n if (engine.isWebGPU) {\r\n shaderLanguage = ShaderLanguage.WGSL;\r\n vertex = (await import(\"./shadersWGSL/msdf.vertex\")).msdfVertexShaderWGSL.shader;\r\n fragment = (await import(\"./shadersWGSL/msdf.fragment\")).msdfPixelShaderWGSL.shader;\r\n } else {\r\n vertex = (await import(\"./shaders/msdf.vertex\")).msdfVertexShader.shader;\r\n fragment = (await import(\"./shaders/msdf.fragment\")).msdfPixelShader.shader;\r\n }\r\n\r\n const textRenderer = new TextRenderer(engine, shaderLanguage, font);\r\n textRenderer._setShaders(vertex, fragment);\r\n\r\n return textRenderer;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babylonjs/addons",
3
- "version": "8.8.5",
3
+ "version": "8.9.1",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "types": "index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "postcompile": "build-tools -c add-js-to-es6"
19
19
  },
20
20
  "devDependencies": {
21
- "@babylonjs/core": "^8.8.5",
21
+ "@babylonjs/core": "^8.9.1",
22
22
  "@dev/addons": "^1.0.0",
23
23
  "@dev/build-tools": "^1.0.0"
24
24
  },
@@ -1,45 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
- const name = "msdfFragmentShader";
3
- const shader = `
4
- #extension GL_OES_standard_derivatives : enable
5
-
6
- precision highp float;
7
-
8
- uniform sampler2D fontAtlas;
9
- uniform vec2 unitRange;
10
- uniform vec2 texelSize;
11
- uniform vec4 uColor;
12
- uniform float thickness;
13
-
14
- varying vec2 atlasUV;
15
-
16
- float median(vec3 msdf) {
17
- return max(min(msdf.r, msdf.g), min(max(msdf.r, msdf.g), msdf.b));
18
- }
19
-
20
- float screenPxRange(sampler2D tex) {
21
- vec2 screenTexSize = vec2(1.0) / fwidth(atlasUV);
22
- return max(0.5 * dot(unitRange, screenTexSize), 1.0);
23
- }
24
-
25
- void main(void)
26
- {
27
- vec3 sdfCenter = texture2D(fontAtlas, atlasUV).rgb;
28
- vec3 sdfLeft = texture2D(fontAtlas, atlasUV - vec2(texelSize.x, 0.0)).rgb;
29
- vec3 sdfRight = texture2D(fontAtlas, atlasUV + vec2(texelSize.x, 0.0)).rgb;
30
- vec3 sdfTop = texture2D(fontAtlas, atlasUV - vec2(0.0, texelSize.y)).rgb;
31
- vec3 sdfBottom = texture2D(fontAtlas, atlasUV + vec2(0.0, texelSize.y)).rgb;
32
-
33
- vec3 sdf = (sdfCenter + sdfLeft + sdfRight + sdfTop + sdfBottom) / 5.0;
34
-
35
- float dist = median(sdfCenter);
36
-
37
- float pxRange = screenPxRange(fontAtlas);
38
- float pxDist = pxRange * (dist - 0.5 + thickness);
39
- float alpha = clamp(pxDist / fwidth(pxDist) + 0.5, 0.0, 1.0);
40
-
41
- gl_FragColor = vec4(uColor.rgb, alpha * uColor.a);
42
- }`;
43
- /** @internal */
44
- export const msdfFragmentShader = { name, shader };
45
- //# sourceMappingURL=fragment.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/webgl/fragment.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAClC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCb,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nconst name = \"msdfFragmentShader\";\r\nconst shader = `\r\n#extension GL_OES_standard_derivatives : enable\r\n\r\nprecision highp float;\r\n\r\nuniform sampler2D fontAtlas;\r\nuniform vec2 unitRange;\r\nuniform vec2 texelSize;\r\nuniform vec4 uColor;\r\nuniform float thickness;\r\n\r\nvarying vec2 atlasUV;\r\n\r\nfloat median(vec3 msdf) {\r\n return max(min(msdf.r, msdf.g), min(max(msdf.r, msdf.g), msdf.b));\r\n}\r\n \r\nfloat screenPxRange(sampler2D tex) {\r\n vec2 screenTexSize = vec2(1.0) / fwidth(atlasUV);\r\n return max(0.5 * dot(unitRange, screenTexSize), 1.0);\r\n}\r\n\r\nvoid main(void)\r\n{\r\n vec3 sdfCenter = texture2D(fontAtlas, atlasUV).rgb;\r\n vec3 sdfLeft = texture2D(fontAtlas, atlasUV - vec2(texelSize.x, 0.0)).rgb;\r\n vec3 sdfRight = texture2D(fontAtlas, atlasUV + vec2(texelSize.x, 0.0)).rgb;\r\n vec3 sdfTop = texture2D(fontAtlas, atlasUV - vec2(0.0, texelSize.y)).rgb;\r\n vec3 sdfBottom = texture2D(fontAtlas, atlasUV + vec2(0.0, texelSize.y)).rgb;\r\n\r\n vec3 sdf = (sdfCenter + sdfLeft + sdfRight + sdfTop + sdfBottom) / 5.0;\r\n\r\n float dist = median(sdfCenter);\r\n\r\n float pxRange = screenPxRange(fontAtlas);\r\n float pxDist = pxRange * (dist - 0.5 + thickness);\r\n float alpha = clamp(pxDist / fwidth(pxDist) + 0.5, 0.0, 1.0);\r\n\r\n gl_FragColor = vec4(uColor.rgb, alpha * uColor.a);\r\n}`;\r\n\r\n/** @internal */\r\nexport const msdfFragmentShader = { name, shader };\r\n"]}
@@ -1,25 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
- const name = "msdfVertexShader";
3
- const shader = `
4
- attribute vec2 offsets;
5
- attribute vec4 world0;
6
- attribute vec4 world1;
7
- attribute vec4 world2;
8
- attribute vec4 world3;
9
- attribute vec4 uvs;
10
-
11
- uniform mat4 parentWorld;
12
- uniform mat4 view;
13
- uniform mat4 projection;
14
-
15
- varying vec2 atlasUV;
16
-
17
- void main(void) {
18
- mat4 world = mat4(world0, world1, world2, world3);
19
- vec3 viewPos = (view * parentWorld * world * vec4(offsets.xy - vec2(0.5, 0.5), 0., 1.0)).xyz;
20
- gl_Position = projection * vec4(viewPos,1.0);
21
- atlasUV = vec2(uvs.x + offsets.x * uvs.z, uvs.y + (1.0 - offsets.y) * uvs.w);
22
- }`;
23
- /** @internal */
24
- export const msdfVertexShader = { name, shader };
25
- //# sourceMappingURL=vertex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vertex.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/webgl/vertex.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAChC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;EAmBb,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nconst name = \"msdfVertexShader\";\r\nconst shader = `\r\nattribute vec2 offsets;\r\nattribute vec4 world0;\r\nattribute vec4 world1;\r\nattribute vec4 world2;\r\nattribute vec4 world3;\r\nattribute vec4 uvs;\r\n\r\nuniform mat4 parentWorld;\r\nuniform mat4 view;\r\nuniform mat4 projection;\r\n\r\nvarying vec2 atlasUV;\r\n\r\nvoid main(void) {\r\n mat4 world = mat4(world0, world1, world2, world3);\r\n vec3 viewPos = (view * parentWorld * world * vec4(offsets.xy - vec2(0.5, 0.5), 0., 1.0)).xyz; \r\n gl_Position = projection * vec4(viewPos,1.0); \r\n atlasUV = vec2(uvs.x + offsets.x * uvs.z, uvs.y + (1.0 - offsets.y) * uvs.w);\r\n}`;\r\n\r\n/** @internal */\r\nexport const msdfVertexShader = { name, shader };\r\n"]}
@@ -1,47 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
- const name = "msdfFragmentShader";
3
- const shader = `
4
- var fontAtlas: texture_2d<f32>;
5
- var fontAtlasSampler: sampler;
6
- uniform unitRange: vec2f;
7
- uniform texelSize: vec2f;
8
- uniform uColor: vec4f;
9
- uniform thickness: f32;
10
-
11
- varying atlasUV: vec2f;
12
-
13
- fn median(msdf: vec3<f32>) -> f32 {
14
- let a = min(msdf.r, msdf.g);
15
- let b = max(msdf.r, msdf.g);
16
- return max(a, min(b, msdf.b));
17
- }
18
-
19
- @fragment
20
- fn main(input: FragmentInputs) -> FragmentOutputs {
21
- let uv = input.atlasUV;
22
-
23
- // Sample center and neighbors
24
- let sdfCenter = textureSample(fontAtlas, fontAtlasSampler, uv).rgb;
25
- let sdfLeft = textureSample(fontAtlas, fontAtlasSampler, uv - vec2<f32>(uniforms.texelSize.x, 0.0)).rgb;
26
- let sdfRight = textureSample(fontAtlas, fontAtlasSampler, uv + vec2<f32>(uniforms.texelSize.x, 0.0)).rgb;
27
- let sdfTop = textureSample(fontAtlas, fontAtlasSampler, uv - vec2<f32>(0.0, uniforms.texelSize.y)).rgb;
28
- let sdfBottom = textureSample(fontAtlas, fontAtlasSampler, uv + vec2<f32>(0.0, uniforms.texelSize.y)).rgb;
29
-
30
- let sdf = (sdfCenter + sdfLeft + sdfRight + sdfTop + sdfBottom) / 5.0;
31
-
32
- let dist = median(sdfCenter);
33
-
34
- // Estimate pixel range in screen space
35
- let dx = dpdx(uv);
36
- let dy = dpdy(uv);
37
- let screenTexSize = vec2<f32>(1.0) / vec2<f32>(length(dx), length(dy));
38
- let pxRange = max(0.5 * dot(uniforms.unitRange, screenTexSize), 1.0);
39
-
40
- let pxDist = pxRange * (dist - 0.5 + uniforms.thickness);
41
- let alpha = clamp(pxDist / length(dpdx(pxDist)) + 0.5, 0.0, 1.0);
42
-
43
- fragmentOutputs.color = vec4<f32>(uniforms.uColor.rgb, alpha * uniforms.uColor.a);
44
- }`;
45
- /** @internal */
46
- export const msdfFragmentShader = { name, shader };
47
- //# sourceMappingURL=fragment.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/webgpu/fragment.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAClC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCb,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nconst name = \"msdfFragmentShader\";\r\nconst shader = `\r\nvar fontAtlas: texture_2d<f32>;\r\nvar fontAtlasSampler: sampler;\r\nuniform unitRange: vec2f;\r\nuniform texelSize: vec2f;\r\nuniform uColor: vec4f;\r\nuniform thickness: f32;\r\n\r\nvarying atlasUV: vec2f;\r\n\r\nfn median(msdf: vec3<f32>) -> f32 {\r\n let a = min(msdf.r, msdf.g);\r\n let b = max(msdf.r, msdf.g);\r\n return max(a, min(b, msdf.b));\r\n}\r\n\r\n@fragment\r\nfn main(input: FragmentInputs) -> FragmentOutputs {\r\n let uv = input.atlasUV;\r\n\r\n // Sample center and neighbors\r\n let sdfCenter = textureSample(fontAtlas, fontAtlasSampler, uv).rgb;\r\n let sdfLeft = textureSample(fontAtlas, fontAtlasSampler, uv - vec2<f32>(uniforms.texelSize.x, 0.0)).rgb;\r\n let sdfRight = textureSample(fontAtlas, fontAtlasSampler, uv + vec2<f32>(uniforms.texelSize.x, 0.0)).rgb;\r\n let sdfTop = textureSample(fontAtlas, fontAtlasSampler, uv - vec2<f32>(0.0, uniforms.texelSize.y)).rgb;\r\n let sdfBottom = textureSample(fontAtlas, fontAtlasSampler, uv + vec2<f32>(0.0, uniforms.texelSize.y)).rgb;\r\n\r\n let sdf = (sdfCenter + sdfLeft + sdfRight + sdfTop + sdfBottom) / 5.0;\r\n\r\n let dist = median(sdfCenter);\r\n\r\n // Estimate pixel range in screen space\r\n let dx = dpdx(uv);\r\n let dy = dpdy(uv);\r\n let screenTexSize = vec2<f32>(1.0) / vec2<f32>(length(dx), length(dy));\r\n let pxRange = max(0.5 * dot(uniforms.unitRange, screenTexSize), 1.0);\r\n\r\n let pxDist = pxRange * (dist - 0.5 + uniforms.thickness);\r\n let alpha = clamp(pxDist / length(dpdx(pxDist)) + 0.5, 0.0, 1.0);\r\n\r\n fragmentOutputs.color = vec4<f32>(uniforms.uColor.rgb, alpha * uniforms.uColor.a);\r\n}`;\r\n\r\n/** @internal */\r\nexport const msdfFragmentShader = { name, shader };\r\n"]}
@@ -1,31 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
- const name = "msdfVertexShader";
3
- const shader = `
4
- attribute offsets: vec2f;
5
- attribute world0: vec4f;
6
- attribute world1: vec4f;
7
- attribute world2: vec4f;
8
- attribute world3: vec4f;
9
- attribute uvs: vec4f;
10
-
11
- uniform parentWorld: mat4x4f;
12
- uniform view: mat4x4f;
13
- uniform projection: mat4x4f;
14
-
15
- varying atlasUV: vec2f;
16
-
17
- @vertex
18
- fn main(input: VertexInputs) -> FragmentInputs {
19
- let world = mat4x4<f32>(input.world0, input.world1, input.world2, input.world3);
20
- let localOffset = vec4<f32>(input.offsets - vec2<f32>(0.5, 0.5), 0.0, 1.0);
21
- let viewPos = (uniforms.view * uniforms.parentWorld * world * localOffset).xyz;
22
- vertexOutputs.position = uniforms.projection * vec4<f32>(viewPos, 1.0);
23
-
24
- vertexOutputs.atlasUV = vec2<f32>(
25
- input.uvs.x + input.offsets.x * input.uvs.z,
26
- input.uvs.y + (1.0 - input.offsets.y) * input.uvs.w
27
- );
28
- }`;
29
- /** @internal */
30
- export const msdfVertexShader = { name, shader };
31
- //# sourceMappingURL=vertex.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vertex.js","sourceRoot":"","sources":["../../../../../dev/addons/src/msdfText/webgpu/vertex.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAChC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;EAyBb,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nconst name = \"msdfVertexShader\";\r\nconst shader = `\r\nattribute offsets: vec2f;\r\nattribute world0: vec4f;\r\nattribute world1: vec4f;\r\nattribute world2: vec4f;\r\nattribute world3: vec4f;\r\nattribute uvs: vec4f;\r\n\r\nuniform parentWorld: mat4x4f;\r\nuniform view: mat4x4f;\r\nuniform projection: mat4x4f;\r\n\r\nvarying atlasUV: vec2f;\r\n\r\n@vertex\r\nfn main(input: VertexInputs) -> FragmentInputs {\r\n let world = mat4x4<f32>(input.world0, input.world1, input.world2, input.world3);\r\n let localOffset = vec4<f32>(input.offsets - vec2<f32>(0.5, 0.5), 0.0, 1.0);\r\n let viewPos = (uniforms.view * uniforms.parentWorld * world * localOffset).xyz;\r\n vertexOutputs.position = uniforms.projection * vec4<f32>(viewPos, 1.0);\r\n\r\n vertexOutputs.atlasUV = vec2<f32>(\r\n input.uvs.x + input.offsets.x * input.uvs.z,\r\n input.uvs.y + (1.0 - input.offsets.y) * input.uvs.w\r\n );\r\n}`;\r\n\r\n/** @internal */\r\nexport const msdfVertexShader = { name, shader };\r\n"]}