@babylonjs/addons 8.6.2 → 8.7.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 (43) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +1 -0
  3. package/index.js.map +1 -1
  4. package/msdfText/fontAsset.d.ts +34 -0
  5. package/msdfText/fontAsset.js +83 -0
  6. package/msdfText/fontAsset.js.map +1 -0
  7. package/msdfText/index.d.ts +3 -0
  8. package/msdfText/index.js +4 -0
  9. package/msdfText/index.js.map +1 -0
  10. package/msdfText/paragraphOptions.d.ts +13 -0
  11. package/msdfText/paragraphOptions.js +13 -0
  12. package/msdfText/paragraphOptions.js.map +1 -0
  13. package/msdfText/sdf/bmFont.d.ts +129 -0
  14. package/msdfText/sdf/bmFont.js +2 -0
  15. package/msdfText/sdf/bmFont.js.map +1 -0
  16. package/msdfText/sdf/font.d.ts +8 -0
  17. package/msdfText/sdf/font.js +2 -0
  18. package/msdfText/sdf/font.js.map +1 -0
  19. package/msdfText/sdf/glyph.d.ts +11 -0
  20. package/msdfText/sdf/glyph.js +2 -0
  21. package/msdfText/sdf/glyph.js.map +1 -0
  22. package/msdfText/sdf/line.d.ts +9 -0
  23. package/msdfText/sdf/line.js +2 -0
  24. package/msdfText/sdf/line.js.map +1 -0
  25. package/msdfText/sdf/paragraph.d.ts +21 -0
  26. package/msdfText/sdf/paragraph.js +130 -0
  27. package/msdfText/sdf/paragraph.js.map +1 -0
  28. package/msdfText/textRenderer.d.ts +99 -0
  29. package/msdfText/textRenderer.js +282 -0
  30. package/msdfText/textRenderer.js.map +1 -0
  31. package/msdfText/webgl/fragment.d.ts +5 -0
  32. package/msdfText/webgl/fragment.js +45 -0
  33. package/msdfText/webgl/fragment.js.map +1 -0
  34. package/msdfText/webgl/vertex.d.ts +5 -0
  35. package/msdfText/webgl/vertex.js +25 -0
  36. package/msdfText/webgl/vertex.js.map +1 -0
  37. package/msdfText/webgpu/fragment.d.ts +5 -0
  38. package/msdfText/webgpu/fragment.js +47 -0
  39. package/msdfText/webgpu/fragment.js.map +1 -0
  40. package/msdfText/webgpu/vertex.d.ts +5 -0
  41. package/msdfText/webgpu/vertex.js +31 -0
  42. package/msdfText/webgpu/vertex.js.map +1 -0
  43. package/package.json +2 -2
@@ -0,0 +1,99 @@
1
+ import type { AbstractEngine } from "@babylonjs/core/Engines/abstractEngine.js";
2
+ import type { IDisposable } from "@babylonjs/core/scene.js";
3
+ import type { Nullable } from "@babylonjs/core/types.js";
4
+ import type { FontAsset } from "./fontAsset.js";
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";
8
+ /**
9
+ * Abstract Node class from Babylon.js
10
+ */
11
+ export interface INodeLike {
12
+ getWorldMatrix(): ThinMatrix;
13
+ }
14
+ /**
15
+ * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique
16
+ * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js
17
+ * #6RLCWP#16
18
+ * Star wars scroller: #6RLCWP#29
19
+ * With metrics: #6RLCWP#35
20
+ * Thickness: #IABMEZ#3
21
+ * Solar system: #9YCDYC#9
22
+ */
23
+ export declare class TextRenderer implements IDisposable {
24
+ private readonly _useVAO;
25
+ private _engine;
26
+ private _shaderLanguage;
27
+ private _vertexBuffers;
28
+ private _spriteBuffer;
29
+ private _worldBuffer;
30
+ private _uvBuffer;
31
+ private _drawWrapperBase;
32
+ private _vertexArrayObject;
33
+ private _font;
34
+ private _charMatrices;
35
+ private _charUvs;
36
+ private _isDirty;
37
+ private _baseLine;
38
+ private _scalingMatrix;
39
+ private _fontScaleMatrix;
40
+ private _offsetMatrix;
41
+ private _translationMatrix;
42
+ private _baseMatrix;
43
+ private _scaledMatrix;
44
+ private _localMatrix;
45
+ private _finalMatrix;
46
+ private _lineMatrix;
47
+ private _parentWorldMatrix;
48
+ private _storedTranslation;
49
+ /**
50
+ * Gets or sets the color of the text
51
+ */
52
+ color: IColor4Like;
53
+ /**
54
+ * Gets or sets the thickness of the text (0 means as defined in the font)
55
+ * Value must be between -0.5 and 0.5
56
+ */
57
+ thicknessControl: number;
58
+ private _parent;
59
+ /**
60
+ * Gets or sets the parent of the text renderer
61
+ */
62
+ get parent(): Nullable<INodeLike>;
63
+ set parent(value: Nullable<INodeLike>);
64
+ /**
65
+ * Gets or sets if the text is billboarded
66
+ */
67
+ isBillboard: boolean;
68
+ /**
69
+ * Gets the number of characters in the text renderer
70
+ */
71
+ get characterCount(): number;
72
+ private constructor();
73
+ private _resizeBuffers;
74
+ private _setShaders;
75
+ /**
76
+ * Add a paragraph of text to the renderer
77
+ * @param text define the text to add
78
+ * @param options define the options to use for the paragraph (optional)
79
+ * @param worldMatrix define the world matrix to use for the paragraph (optional)
80
+ */
81
+ addParagraph(text: string, options?: Partial<ParagraphOptions>, worldMatrix?: IMatrixLike): void;
82
+ /**
83
+ * Render the text using the provided view and projection matrices
84
+ * @param viewMatrix define the view matrix to use
85
+ * @param projectionMatrix define the projection matrix to use
86
+ */
87
+ render(viewMatrix: IMatrixLike, projectionMatrix: IMatrixLike): void;
88
+ /**
89
+ * Release associated resources
90
+ */
91
+ dispose(): void;
92
+ /**
93
+ * Creates a new TextRenderer instance asynchronously
94
+ * @param font define the font asset to use
95
+ * @param engine define the engine to use
96
+ * @returns a promise that resolves to the created TextRenderer instance
97
+ */
98
+ static CreateTextRendererAsync(font: FontAsset, engine: AbstractEngine): Promise<TextRenderer>;
99
+ }
@@ -0,0 +1,282 @@
1
+ import { Buffer } from "@babylonjs/core/Buffers/buffer.js";
2
+ import { Constants } from "@babylonjs/core/Engines/constants.js";
3
+ import { DrawWrapper } from "@babylonjs/core/Materials/drawWrapper.js";
4
+ import { SdfTextParagraph } from "./sdf/paragraph.js";
5
+ import { ThinMatrix } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.js";
6
+ import { CopyMatrixToArray, IdentityMatrixToRef, InvertMatrixToRef, MultiplyMatricesToRef, ScalingMatrixToRef, TranslationMatrixToRef, } from "@babylonjs/core/Maths/ThinMaths/thinMath.matrix.functions.js";
7
+ /**
8
+ * Class used to render text using MSDF (Multi-channel Signed Distance Field) technique
9
+ * Thanks a lot to the work of Bhushan_Wagh and zb_sj for their amazing work on MSDF for Babylon.js
10
+ * #6RLCWP#16
11
+ * Star wars scroller: #6RLCWP#29
12
+ * With metrics: #6RLCWP#35
13
+ * Thickness: #IABMEZ#3
14
+ * Solar system: #9YCDYC#9
15
+ */
16
+ export class TextRenderer {
17
+ /**
18
+ * Gets or sets the parent of the text renderer
19
+ */
20
+ get parent() {
21
+ return this._parent;
22
+ }
23
+ set parent(value) {
24
+ this._parent = value;
25
+ }
26
+ /**
27
+ * Gets the number of characters in the text renderer
28
+ */
29
+ get characterCount() {
30
+ return this._charMatrices.length / 16;
31
+ }
32
+ constructor(engine, shaderLanguage = 0 /* ShaderLanguage.GLSL */, font) {
33
+ this._useVAO = false;
34
+ this._vertexBuffers = {};
35
+ this._charMatrices = new Array();
36
+ this._charUvs = new Array();
37
+ this._isDirty = true;
38
+ this._baseLine = 0;
39
+ // Cache
40
+ this._scalingMatrix = new ThinMatrix();
41
+ this._fontScaleMatrix = new ThinMatrix();
42
+ this._offsetMatrix = new ThinMatrix();
43
+ this._translationMatrix = new ThinMatrix();
44
+ this._baseMatrix = new ThinMatrix();
45
+ this._scaledMatrix = new ThinMatrix();
46
+ this._localMatrix = new ThinMatrix();
47
+ this._finalMatrix = new ThinMatrix();
48
+ this._lineMatrix = new ThinMatrix();
49
+ this._parentWorldMatrix = new ThinMatrix();
50
+ this._storedTranslation = { x: 0, y: 0, z: 0 };
51
+ /**
52
+ * Gets or sets the color of the text
53
+ */
54
+ this.color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
55
+ /**
56
+ * Gets or sets the thickness of the text (0 means as defined in the font)
57
+ * Value must be between -0.5 and 0.5
58
+ */
59
+ this.thicknessControl = 0;
60
+ this._parent = null;
61
+ /**
62
+ * Gets or sets if the text is billboarded
63
+ */
64
+ this.isBillboard = false;
65
+ this._engine = engine;
66
+ this._shaderLanguage = shaderLanguage;
67
+ this._font = font;
68
+ this._baseLine = font._font.common.lineHeight * font.scale;
69
+ this._useVAO = engine.getCaps().vertexArrayObject && !engine.disableVertexArrayObjects;
70
+ // Main vertex buffer
71
+ const spriteData = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
72
+ this._spriteBuffer = new Buffer(engine, spriteData, false, 2);
73
+ this._vertexBuffers["offsets"] = this._spriteBuffer.createVertexBuffer("offsets", 0, 2);
74
+ // Instances
75
+ this._resizeBuffers(128);
76
+ }
77
+ _resizeBuffers(capacity) {
78
+ if (this._worldBuffer) {
79
+ this._worldBuffer.dispose();
80
+ this._worldBuffer = null;
81
+ }
82
+ if (this._uvBuffer) {
83
+ this._uvBuffer.dispose();
84
+ this._uvBuffer = null;
85
+ }
86
+ this._worldBuffer = new Buffer(this._engine, new Float32Array(capacity * 16), true, 16);
87
+ this._vertexBuffers["world0"] = this._worldBuffer.createVertexBuffer("world0", 0, 4, 16, true);
88
+ this._vertexBuffers["world1"] = this._worldBuffer.createVertexBuffer("world1", 4, 4, 16, true);
89
+ this._vertexBuffers["world2"] = this._worldBuffer.createVertexBuffer("world2", 8, 4, 16, true);
90
+ this._vertexBuffers["world3"] = this._worldBuffer.createVertexBuffer("world3", 12, 4, 16, true);
91
+ this._uvBuffer = new Buffer(this._engine, new Float32Array(capacity * 4), true, 4);
92
+ this._vertexBuffers["uvs"] = this._uvBuffer.createVertexBuffer("uvs", 0, 4, 4, true);
93
+ }
94
+ _setShaders(vertex, fragment) {
95
+ this._drawWrapperBase?.dispose();
96
+ this._drawWrapperBase = new DrawWrapper(this._engine);
97
+ if (this._drawWrapperBase.drawContext) {
98
+ this._drawWrapperBase.drawContext.useInstancing = true;
99
+ }
100
+ const defines = "";
101
+ this._drawWrapperBase.effect = this._engine.createEffect({
102
+ vertexSource: vertex,
103
+ fragmentSource: fragment,
104
+ }, ["offsets", "world0", "world1", "world2", "world3", "uvs"], ["parentWorld", "view", "projection", "uColor", "unitRange", "texelSize", "thickness"], ["fontAtlas"], defines, undefined, undefined, undefined, undefined, this._shaderLanguage);
105
+ this._drawWrapperBase.effect._refCount++;
106
+ }
107
+ /**
108
+ * Add a paragraph of text to the renderer
109
+ * @param text define the text to add
110
+ * @param options define the options to use for the paragraph (optional)
111
+ * @param worldMatrix define the world matrix to use for the paragraph (optional)
112
+ */
113
+ addParagraph(text, options, worldMatrix) {
114
+ const paragraph = new SdfTextParagraph(text, this._font, options);
115
+ const fontScale = this._font.scale;
116
+ const texWidth = this._font._font.common.scaleW;
117
+ const texHeight = this._font._font.common.scaleH;
118
+ const glyphs = paragraph.glyphs.filter((g) => g.char.page >= 0);
119
+ let worldMatrixToUse = worldMatrix;
120
+ if (!worldMatrixToUse) {
121
+ const lineHeight = paragraph.lineHeight * fontScale;
122
+ const lineOffset = (paragraph.lines.length * lineHeight) / 2;
123
+ TranslationMatrixToRef(0, this._baseLine - lineOffset, 0, this._lineMatrix);
124
+ worldMatrixToUse = this._lineMatrix;
125
+ }
126
+ ScalingMatrixToRef(fontScale, fontScale, 1.0, this._fontScaleMatrix);
127
+ TranslationMatrixToRef(0.5, -0.5, 0, this._offsetMatrix);
128
+ const charsUvsBase = this._charUvs.length;
129
+ const matricesBase = this._charMatrices.length;
130
+ glyphs.forEach((g, i) => {
131
+ this._charUvs[charsUvsBase + i * 4 + 0] = g.char.x / texWidth;
132
+ this._charUvs[charsUvsBase + i * 4 + 1] = g.char.y / texHeight;
133
+ this._charUvs[charsUvsBase + i * 4 + 2] = g.char.width / texWidth;
134
+ this._charUvs[charsUvsBase + i * 4 + 3] = g.char.height / texHeight;
135
+ const x = g.x;
136
+ const y = -g.y;
137
+ ScalingMatrixToRef(g.char.width, g.char.height, 1.0, this._scalingMatrix);
138
+ MultiplyMatricesToRef(this._offsetMatrix, this._scalingMatrix, this._baseMatrix);
139
+ TranslationMatrixToRef(x * fontScale, y * fontScale, 0.0, this._translationMatrix);
140
+ MultiplyMatricesToRef(this._baseMatrix, this._fontScaleMatrix, this._scaledMatrix);
141
+ MultiplyMatricesToRef(this._scaledMatrix, this._translationMatrix, this._localMatrix);
142
+ MultiplyMatricesToRef(this._localMatrix, worldMatrixToUse, this._finalMatrix);
143
+ CopyMatrixToArray(this._finalMatrix, this._charMatrices, matricesBase + i * 16);
144
+ });
145
+ this._isDirty = true;
146
+ this._baseLine -= paragraph.lineHeight * fontScale * paragraph.lines.length;
147
+ }
148
+ /**
149
+ * Render the text using the provided view and projection matrices
150
+ * @param viewMatrix define the view matrix to use
151
+ * @param projectionMatrix define the projection matrix to use
152
+ */
153
+ render(viewMatrix, projectionMatrix) {
154
+ const drawWrapper = this._drawWrapperBase;
155
+ const effect = drawWrapper.effect;
156
+ // Check
157
+ if (!effect.isReady()) {
158
+ return;
159
+ }
160
+ const engine = this._engine;
161
+ engine.setState(false);
162
+ 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.asArray());
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;
189
+ }
190
+ else {
191
+ if (this._parent) {
192
+ CopyMatrixToArray(this._parent.getWorldMatrix(), this._parentWorldMatrix.asArray());
193
+ }
194
+ else {
195
+ IdentityMatrixToRef(this._parentWorldMatrix);
196
+ }
197
+ }
198
+ effect.setMatrix("parentWorld", this._parentWorldMatrix);
199
+ effect.setMatrix("view", viewMatrix);
200
+ effect.setMatrix("projection", projectionMatrix);
201
+ // 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
+ 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
+ effect.setDirectColor4("uColor", this.color);
209
+ effect.setFloat("thickness", this.thicknessControl * 0.9);
210
+ const instanceCount = this._charMatrices.length / 16;
211
+ // Need update?
212
+ if (this._isDirty) {
213
+ this._isDirty = false;
214
+ if (this._worldBuffer.getBuffer().capacity / 4 < instanceCount * 16) {
215
+ this._resizeBuffers(instanceCount);
216
+ }
217
+ this._worldBuffer.update(this._charMatrices);
218
+ this._uvBuffer.update(this._charUvs);
219
+ }
220
+ if (this._useVAO) {
221
+ if (!this._vertexArrayObject) {
222
+ this._vertexArrayObject = engine.recordVertexArrayObject(this._vertexBuffers, null, effect);
223
+ }
224
+ engine.bindVertexArrayObject(this._vertexArrayObject, null);
225
+ }
226
+ else {
227
+ // VBOs
228
+ engine.bindBuffers(this._vertexBuffers, null, effect);
229
+ }
230
+ engine.setAlphaMode(Constants.ALPHA_COMBINE);
231
+ engine.drawArraysType(Constants.MATERIAL_TriangleStripDrawMode, 0, 4, instanceCount);
232
+ engine.unbindInstanceAttributes();
233
+ }
234
+ /**
235
+ * Release associated resources
236
+ */
237
+ dispose() {
238
+ if (this._worldBuffer) {
239
+ this._worldBuffer.dispose();
240
+ this._worldBuffer = null;
241
+ }
242
+ if (this._uvBuffer) {
243
+ this._uvBuffer.dispose();
244
+ this._uvBuffer = null;
245
+ }
246
+ if (this._spriteBuffer) {
247
+ this._spriteBuffer.dispose();
248
+ this._spriteBuffer = null;
249
+ }
250
+ if (this._vertexArrayObject) {
251
+ this._engine.releaseVertexArrayObject(this._vertexArrayObject);
252
+ this._vertexArrayObject = null;
253
+ }
254
+ }
255
+ /**
256
+ * Creates a new TextRenderer instance asynchronously
257
+ * @param font define the font asset to use
258
+ * @param engine define the engine to use
259
+ * @returns a promise that resolves to the created TextRenderer instance
260
+ */
261
+ static async CreateTextRendererAsync(font, engine) {
262
+ if (!engine.getCaps().instancedArrays || !engine._features.supportSpriteInstancing) {
263
+ throw new Error("Instanced arrays are required for MSDF text rendering.");
264
+ }
265
+ let shaderLanguage = 0 /* ShaderLanguage.GLSL */;
266
+ let vertex = "";
267
+ let fragment = "";
268
+ if (engine.isWebGPU) {
269
+ shaderLanguage = 1 /* ShaderLanguage.WGSL */;
270
+ vertex = (await import("./webgpu/vertex.js")).msdfVertexShader.shader;
271
+ fragment = (await import("./webgpu/fragment.js")).msdfFragmentShader.shader;
272
+ }
273
+ else {
274
+ vertex = (await import("./webgl/vertex.js")).msdfVertexShader.shader;
275
+ fragment = (await import("./webgl/fragment.js")).msdfFragmentShader.shader;
276
+ }
277
+ const textRenderer = new TextRenderer(engine, shaderLanguage, font);
278
+ textRenderer._setShaders(vertex, fragment);
279
+ return textRenderer;
280
+ }
281
+ }
282
+ //# sourceMappingURL=textRenderer.js.map
@@ -0,0 +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 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.asArray());\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 CopyMatrixToArray(this._parent.getWorldMatrix(), this._parentWorldMatrix.asArray());\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"]}
@@ -0,0 +1,5 @@
1
+ /** @internal */
2
+ export declare const msdfFragmentShader: {
3
+ name: string;
4
+ shader: string;
5
+ };
@@ -0,0 +1,45 @@
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
@@ -0,0 +1 @@
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"]}
@@ -0,0 +1,5 @@
1
+ /** @internal */
2
+ export declare const msdfVertexShader: {
3
+ name: string;
4
+ shader: string;
5
+ };
@@ -0,0 +1,25 @@
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
@@ -0,0 +1 @@
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"]}
@@ -0,0 +1,5 @@
1
+ /** @internal */
2
+ export declare const msdfFragmentShader: {
3
+ name: string;
4
+ shader: string;
5
+ };
@@ -0,0 +1,47 @@
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
@@ -0,0 +1 @@
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"]}
@@ -0,0 +1,5 @@
1
+ /** @internal */
2
+ export declare const msdfVertexShader: {
3
+ name: string;
4
+ shader: string;
5
+ };
@@ -0,0 +1,31 @@
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
@@ -0,0 +1 @@
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"]}