Skip to content

Commit

Permalink
Version 0.10.0 Alpha.5 [Prerelease]
Browse files Browse the repository at this point in the history
Warning: This commit hash may not be preserved!

Debug state: The new GPU-resident text has been fully verified.
  • Loading branch information
Dreaming381 committed Apr 20, 2024
1 parent cd34426 commit 25dcfd8
Show file tree
Hide file tree
Showing 44 changed files with 3,005 additions and 278 deletions.
14 changes: 7 additions & 7 deletions Calligraphics/Authoring/BakingSystems/FontSmartBlobberSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,12 @@ protected override void OnUpdate()
public static unsafe BlobAssetReference<FontBlob> BakeFont(FontAsset font, Material material)
{
material.SetFloat("_WeightNormal", font.regularStyleWeight);
material.SetFloat("_WeightBold", font.boldStyleWeight);
material.SetFloat("_WeightBold", font.boldStyleWeight);
float materialPadding = material.GetPaddingForText(false, false);

var builder = new BlobBuilder(Allocator.Temp);
ref FontBlob fontBlobRoot = ref builder.ConstructRoot<FontBlob>();
fontBlobRoot.name = font.name;
fontBlobRoot.scale = font.faceInfo.scale;
fontBlobRoot.pointSize = font.faceInfo.pointSize;
fontBlobRoot.baseLine = font.faceInfo.baseline;
Expand All @@ -122,12 +123,11 @@ public static unsafe BlobAssetReference<FontBlob> BakeFont(FontAsset font, Mater
fontBlobRoot.regularStyleWeight = font.regularStyleWeight;
fontBlobRoot.boldStyleSpacing = font.boldStyleSpacing;
fontBlobRoot.boldStyleWeight = font.boldStyleWeight;
fontBlobRoot.italicsStyleSlant = font.italicStyleSlant;
fontBlobRoot.italicsStyleSlant = font.italicStyleSlant;
fontBlobRoot.atlasWidth = font.atlasWidth;
fontBlobRoot.atlasHeight = font.atlasHeight;
fontBlobRoot.materialPadding = materialPadding;


var adjustmentCacheBefore = new NativeList<int2>(Allocator.TempJob);
var adjustmentCacheAfter = new NativeList<int2>(Allocator.TempJob);
var glyphToCharacterMap = new NativeHashMap<int, int>(font.characterTable.Count, Allocator.TempJob);
Expand Down Expand Up @@ -179,10 +179,10 @@ public static unsafe BlobAssetReference<FontBlob> BakeFont(FontAsset font, Mater
{
ref GlyphBlob glyphBlob = ref glyphBuilder[i];

glyphBlob.unicode = character.unicode;
glyphBlob.glyphScale = character.glyph.scale;
glyphBlob.glyphMetrics = character.glyph.metrics;
glyphBlob.glyphRect = character.glyph.glyphRect;
glyphBlob.unicode = character.unicode;
glyphBlob.glyphScale = character.glyph.scale;
glyphBlob.glyphMetrics = character.glyph.metrics;
glyphBlob.glyphRect = character.glyph.glyphRect;

//Add kerning adjustments
adjustmentCacheBefore.Clear();
Expand Down
14 changes: 11 additions & 3 deletions Calligraphics/Authoring/TextRendererAuthoring.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ public class TextRendererAuthoring : MonoBehaviour
public HorizontalAlignmentOptions horizontalAlignment = HorizontalAlignmentOptions.Left;
public VerticalAlignmentOptions verticalAlignment = VerticalAlignmentOptions.Top;
public bool isOrthographic;
public bool enableKerning = true;
public bool enableKerning = true;
public FontStyles fontStyle;
public FontWeight fontWeight;

public Color32 color = UnityEngine.Color.white;

public List<FontMaterialPair> fontsAndMaterials;

[Tooltip("If enabled, text is stored perpetually in GPU memory and always uploaded on change, regardless of visibility.")]
public bool gpuResident;
}

[Serializable]
Expand All @@ -56,8 +59,11 @@ public override void Bake(TextRendererAuthoring authoring)

var entity = GetEntity(TransformUsageFlags.Renderable);

//Fonts
// Fonts and rendering
AddFontRendering(entity, authoring.fontsAndMaterials[0]);
if (authoring.gpuResident)
AddComponent<GpuResidentTextTag>(entity);

if (authoring.fontsAndMaterials.Count > 1)
{
AddComponent<TextMaterialMaskShaderIndex>(entity);
Expand All @@ -70,10 +76,12 @@ public override void Bake(TextRendererAuthoring authoring)
AddComponent<TextMaterialMaskShaderIndex>(newEntity);
AddBuffer<RenderGlyphMask>(newEntity);
additionalEntities.Add(newEntity);
if (authoring.gpuResident)
AddComponent<GpuResidentTextTag>(newEntity);
}
}

//Text Content
// Text Content
var calliString = new CalliString(AddBuffer<CalliByte>(entity));
calliString.Append(authoring.text);
AddComponent(entity, new TextBaseConfiguration
Expand Down
11 changes: 6 additions & 5 deletions Calligraphics/Components/FontBlob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Latios.Calligraphics
//TODO: Underlay, Bold, Smallcaps
public struct FontBlob
{
public FixedString128Bytes name;
public BlobArray<GlyphBlob> characters;
public BlobArray<BlobArray<GlyphLookup> > glyphLookupMap;
public BlobArray<AdjustmentPair> adjustmentPairs;
Expand Down Expand Up @@ -52,11 +53,11 @@ public struct FontBlob

public struct GlyphBlob
{
public uint glyphIndex;
public uint unicode;
public GlyphMetrics glyphMetrics;
public GlyphRect glyphRect;
public float glyphScale;
public uint glyphIndex;
public uint unicode;
public GlyphMetrics glyphMetrics;
public GlyphRect glyphRect;
public float glyphScale;

public AdjustmentPairLookupByGlyph glyphAdjustmentsLookup;
}
Expand Down
30 changes: 30 additions & 0 deletions Calligraphics/Components/TextRenderingComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ public struct RenderGlyphMask : IBufferElementData
public uint lowerOffsetUpperMask16;
}

/// <summary>
/// When this tag is present, the text is treated as GPU-resident. Such text always
/// consumes GPU memory, even when not visible, and that memory can be prone to fragmentation.
/// It is recommended to only use this for static text which will appear for steady durations
/// of time or when the number known to exist is suitably small. An example of an appropriate
/// use case would be player names in a game session that had a max capacity of players of
/// 1024 or less.
/// </summary>
public struct GpuResidentTextTag : IComponentData { }

internal struct GlyphCountThisFrame : IComponentData
{
public uint glyphCount;
Expand All @@ -181,5 +191,25 @@ internal struct MaskCountThisFrame : IComponentData
{
public uint maskCount;
}

internal struct GpuResidentUpdateFlag : IComponentData, IEnableableComponent { }

internal struct GpuResidentAllocation : ICleanupComponentData
{
public uint glyphStart;
public uint glyphCount;
public uint maskStart;
public uint maskCount;
}

internal struct GpuResidentGlyphCount : IComponentData
{
public uint glyphCount;
}

internal struct GpuResidentMaskCount : IComponentData
{
public uint maskCount;
}
}

2 changes: 1 addition & 1 deletion Calligraphics/Fonts/LiberationSans SDF.asset
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Material:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
m_CustomRenderQueue: 3000
stringTagMap:
RenderType: Transparent
disabledShaderPasses:
Expand Down
2 changes: 2 additions & 0 deletions Calligraphics/Internal/FontMaterialSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ internal unsafe struct FontMaterialSet

public ref FontBlob this[int index] => ref m_fontMaterialArray[index].font;

public int length => m_fontMaterialArray.Length;

public void WriteFontMaterialIndexForGlyph(int index)
{
if (!m_hasMultipleFonts)
Expand Down
53 changes: 30 additions & 23 deletions Calligraphics/Internal/GlyphGeneration.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices;
using Latios.Calligraphics.Rendering;
using Latios.Calligraphics.RichText;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Entities;
Expand Down Expand Up @@ -36,7 +36,6 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
bool prevWasSpace = false;
int lineCount = 0;
bool isLineStart = true;
ref FontBlob font = ref fontMaterialSet[0];

var calliString = new CalliString(calliBytes);
var characterEnumerator = calliString.GetEnumerator();
Expand All @@ -51,14 +50,16 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
{
textConfiguration.m_isParsingText = true;
// Check if Tag is valid. If valid, skip to the end of the validated tag.
if (RichTextParser.ValidateHtmlTag(in calliString, ref characterEnumerator, ref font, in baseConfiguration, ref textConfiguration, ref richTextTagIdentifiers))
if (RichTextParser.ValidateHtmlTag(in calliString, ref characterEnumerator, ref fontMaterialSet, in baseConfiguration, ref textConfiguration,
ref richTextTagIdentifiers))
{
// Continue to next character
continue;
}
}
#endregion

ref FontBlob font = ref fontMaterialSet[textConfiguration.m_currentFontMaterialIndex];
textConfiguration.m_isParsingText = false;

// Handle Font Styles like LowerCase, UpperCase and SmallCaps.
Expand Down Expand Up @@ -131,30 +132,32 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
blColor = textConfiguration.m_htmlColor,
tlColor = textConfiguration.m_htmlColor,
trColor = textConfiguration.m_htmlColor,
brColor = textConfiguration.m_htmlColor,
brColor = textConfiguration.m_htmlColor,
};

// Set Padding based on selected font style
#region Handle Style Padding
float boldSpacingAdjustment = 0;
float style_padding = 0;
float style_padding = 0;
if ((textConfiguration.m_fontStyleInternal & FontStyles.Bold) == FontStyles.Bold)
{
style_padding = 0;
style_padding = 0;
boldSpacingAdjustment = font.boldStyleSpacing;
}
#endregion Handle Style Padding

var adjustedScale = textConfiguration.m_currentFontSize * smallCapsMultiplier / font.pointSize * font.scale * (baseConfiguration.isOrthographic ? 1 : 0.1f);
var currentElementScale = adjustedScale * textConfiguration.m_fontScaleMultiplier * glyphBlob.glyphScale; //* m_cached_TextElement.m_Scale
float currentEmScale = baseConfiguration.fontSize * 0.01f * (baseConfiguration.isOrthographic? 1 : 0.1f);
var adjustedScale = textConfiguration.m_currentFontSize * smallCapsMultiplier / font.pointSize * font.scale *
(baseConfiguration.isOrthographic ? 1 : 0.1f);
var currentElementScale = adjustedScale * textConfiguration.m_fontScaleMultiplier * glyphBlob.glyphScale; //* m_cached_TextElement.m_Scale
float currentEmScale = baseConfiguration.fontSize * 0.01f * (baseConfiguration.isOrthographic ? 1 : 0.1f);

// Determine the position of the vertices of the Character
#region Calculate Vertices Position
var currentGlyphMetrics = glyphBlob.glyphMetrics;
var currentGlyphMetrics = glyphBlob.glyphMetrics;
float2 topLeft;
topLeft.x = (currentGlyphMetrics.horizontalBearingX * textConfiguration.m_FXScale.x - font.materialPadding - style_padding) * currentElementScale;
topLeft.y = (currentGlyphMetrics.horizontalBearingY + font.materialPadding) * currentElementScale - textConfiguration.m_lineOffset + textConfiguration.m_baselineOffset;
topLeft.x = (currentGlyphMetrics.horizontalBearingX * textConfiguration.m_FXScale.x - font.materialPadding - style_padding) * currentElementScale;
topLeft.y = (currentGlyphMetrics.horizontalBearingY + font.materialPadding) * currentElementScale - textConfiguration.m_lineOffset +
textConfiguration.m_baselineOffset;

float2 bottomLeft;
bottomLeft.x = topLeft.x;
Expand All @@ -170,7 +173,7 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
#endregion

#region Setup UVA
var glyphRect = glyphBlob.glyphRect;
var glyphRect = glyphBlob.glyphRect;
float2 blUVA, tlUVA, trUVA, brUVA;
blUVA.x = (glyphRect.x - font.materialPadding - style_padding) / font.atlasWidth;
blUVA.y = (glyphRect.y - font.materialPadding - style_padding) / font.atlasHeight;
Expand Down Expand Up @@ -198,9 +201,9 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
brUVC.x = 1;

//m_verticalMapping case case TextureMappingOptions.Character
blUVC.y = 0;
tlUVC.y = 1;
trUVC.y = 1;
blUVC.y = 0;
tlUVC.y = 1;
trUVC.y = 1;
brUVC.y = 0;

renderGlyph.blUVB = blUVC;
Expand All @@ -217,7 +220,9 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
float shear = textConfiguration.m_italicAngle * 0.01f;
float2 topShear = new float2(shear * ((currentGlyphMetrics.horizontalBearingY + font.materialPadding + style_padding) * currentElementScale), 0);
float2 bottomShear =
new float2(shear * (((currentGlyphMetrics.horizontalBearingY - currentGlyphMetrics.height - font.materialPadding - style_padding)) * currentElementScale), 0);
new float2(
shear * (((currentGlyphMetrics.horizontalBearingY - currentGlyphMetrics.height - font.materialPadding - style_padding)) * currentElementScale),
0);
float2 shearAdjustment = (topShear - bottomShear) * 0.5f;

topShear -= shearAdjustment;
Expand All @@ -232,15 +237,15 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
}
#endregion Handle Italics & Shearing


// Handle Character FX Rotation
#region Handle Character FX Rotation
renderGlyph.rotationCCW = textConfiguration.m_FXRotationAngle;
#endregion

#region handle bold
var xScale = textConfiguration.m_currentFontSize;// * math.abs(lossyScale) * (1 - m_charWidthAdjDelta);
if ((textConfiguration.m_fontStyleInternal & FontStyles.Bold) == FontStyles.Bold) xScale *= -1;
var xScale = textConfiguration.m_currentFontSize; // * math.abs(lossyScale) * (1 - m_charWidthAdjDelta);
if ((textConfiguration.m_fontStyleInternal & FontStyles.Bold) == FontStyles.Bold)
xScale *= -1;

renderGlyph.scale = xScale;
#endregion
Expand Down Expand Up @@ -312,7 +317,9 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
adjustmentOffset.x = glyphAdjustments.xPlacement * currentElementScale;
adjustmentOffset.y = glyphAdjustments.yPlacement * currentElementScale;

cumulativeOffset.x += ((currentGlyphMetrics.horizontalAdvance * textConfiguration.m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (font.regularStyleSpacing + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + textConfiguration.m_cSpacing);// * (1 - m_charWidthAdjDelta);
cumulativeOffset.x +=
((currentGlyphMetrics.horizontalAdvance * textConfiguration.m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale +
(font.regularStyleSpacing + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + textConfiguration.m_cSpacing); // * (1 - m_charWidthAdjDelta);
cumulativeOffset.y += glyphAdjustments.yAdvance * currentElementScale;
#endregion

Expand Down Expand Up @@ -409,7 +416,7 @@ internal static unsafe void CreateRenderGlyphs(ref DynamicBuffer<RenderGlyph> re
ApplyHorizontalAlignmentToGlyphs(ref finalGlyphsLine, ref characterGlyphIndicesWithPreceedingSpacesInLine, baseConfiguration.maxLineWidth, overrideMode);
}
lineCount++;
ApplyVerticalAlignmentToGlyphs(ref renderGlyphs, lineCount, baseConfiguration.verticalAlignment, ref font, baseConfiguration.fontSize);
ApplyVerticalAlignmentToGlyphs(ref renderGlyphs, lineCount, baseConfiguration.verticalAlignment, ref fontMaterialSet[0], baseConfiguration.fontSize);
}

static unsafe void ApplyHorizontalAlignmentToGlyphs(ref NativeArray<RenderGlyph> glyphs,
Expand Down
Loading

0 comments on commit 25dcfd8

Please sign in to comment.