Last active
October 28, 2025 17:02
-
Star
(185)
You must be signed in to star a gist -
Fork
(15)
You must be signed in to fork a gist
-
-
Save FreyaHolmer/71717be9f3030c1b0990d3ed1ae833e3 to your computer and use it in GitHub Desktop.
Revisions
-
FreyaHolmer revised this gist
Aug 11, 2024 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -14,8 +14,8 @@ // - billboarded to always face the camera // - you can get pxCoord from the frag shader "SV_POSITION" input float DrawNumberAtPxPos(float2 pxCoord, float2 pxPos, float number, float fontScale = 2, int decimalCount = 3); float DrawNumberAtLocalPos(float2 pxCoord, float3 localPos, float number, float scale = 2, int decimalCount = 3); float DrawNumberAtWorldPos(float2 pxCoord, float3 worldPos, float number, float scale = 2, int decimalCount = 3); // digit rendering static uint dBits[5] = { @@ -139,13 +139,13 @@ float2 ClipToPixel(float4 clip) float2 LocalToPixel(float3 locPos) { return ClipToPixel(UnityObjectToClipPos(float4(locPos, 1))); } float2 WorldToPixel(float3 wPos) { return ClipToPixel(UnityWorldToClipPos(float4(wPos, 1))); } float DrawNumberAtLocalPos(float2 pxCoord, float3 localPos, float number, float scale = 2, int decimalCount = 3) { const float2 pxPos = LocalToPixel(localPos); return DrawNumberAtPxPos(pxCoord, pxPos, number, scale, decimalCount); } float DrawNumberAtWorldPos(float2 pxCoord, float3 worldPos, float number, float scale = 2, int decimalCount = 3) { const float2 pxPos = WorldToPixel(worldPos); return DrawNumberAtPxPos(pxCoord, pxPos, number, scale, decimalCount); -
FreyaHolmer revised this gist
Aug 11, 2024 . No changes.There are no files selected for viewing
-
FreyaHolmer created this gist
Aug 11, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,152 @@ /////////////////////////////////////////////////////////////////////////////// // ABOUT: A unity Shader .cginc to draw numbers in the fragment shader // AUTHOR: Freya Holmér // LICENSE: Use for whatever, commercial or otherwise! // Don't hold me liable for issues though // But pls credit me if it works super well <3 // LIMITATIONS: There's some precision loss beyond 3 decimal places // CONTRIBUTORS: yes please! if you know a more precise way to get // decimal digits then pls lemme know! // GetDecimalSymbolAt() could use some more love/precision // These are the main drawing functions: // - returns white text on black background (though trailing zeroes are gray) // - billboarded to always face the camera // - you can get pxCoord from the frag shader "SV_POSITION" input float DrawNumberAtPxPos(float2 pxCoord, float2 pxPos, float number, float fontScale = 2, int decimalCount = 3); float DrawNumberAtLocalPos(float3 pxCoord, float3 localPos, float number, float scale = 2, int decimalCount = 3); float DrawNumberAtWorldPos(float3 pxCoord, float3 worldPos, float number, float scale = 2, int decimalCount = 3); // digit rendering static uint dBits[5] = { 3959160828, 2828738996, 2881485308, 2853333412, 3958634981 }; static uint po10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000}; float DrawDigit(int2 px, const int digit) { if (px.x < 0 || px.x > 2 || px.y < 0 || px.y > 4) return 0; // pixel out of bounds const int xId = (digit == -1) ? 18 : 31 - (3 * digit + px.x); return (dBits[4 - px.y] & 1 << xId) != 0; } // indexed like: XXX.0123 void GetDecimalSymbolAt(const float v, const int i, const int decimalCount, out int symbol, out float opacity) { // hide if outside the decimal range if (i > min(decimalCount - 1, 6)) { symbol = 0; opacity = 0; return; } // get the i:th decimal const float scale = po10[i + 1]; const float scaledF = abs(v) * scale; symbol = (int)(scaledF) % 10; // fade trailing zeroes opacity = (frac(scaledF / 10) != 0) ? 1 : 0.5; } // indexed like: 210.XXX void GetIntSymbolAt(const float v, int i, out int symbol, out float opacity) { // don't render more than 9 digits if (i <= 9) { const int scale = po10[i]; const float vAbs = abs(v); // digits if (vAbs >= scale) { const int it = floor(vAbs); const int rem = it / scale; symbol = rem % 10; opacity = 1; return; } // minus symbol if ((v < 0) & (vAbs * 10 >= scale)) { symbol = -1; opacity = 1; return; } } // leading zeroes symbol = 0; opacity = 0; } // Get the digit at the given index of a floating point number // with -45.78, then with a given dIndex: // [-3] = - (digit -1) // [-2] = 4 // [-1] = 5 // [ 0] = . (digit 10) // [ 1] = 7 // [ 2] = 8 void GetSymbolAtPositionInFloat(float number, int dIndex, int decimalCount, out int symbol, out float opacity) { opacity = 1; if (dIndex == 0) symbol = 10; // period else if (dIndex > 0) GetDecimalSymbolAt(number, dIndex - 1, decimalCount, symbol, opacity); else GetIntSymbolAt(number, -dIndex - 1, symbol, opacity); } // Given a pixel coordinate pxCoord, draws a number at pxPos float DrawNumberAtPxPos(float2 pxCoord, float2 pxPos, float number, float fontScale = 2, int decimalCount = 3) { int2 p = (int2)(floor((pxCoord - pxPos) / fontScale)); // p.y += 0; // 0 = bottom aligned, 2 = vert. center aligned, 5 = top aligned // p.x += 0; // 0 = integers are directly to the left, decimal separator and decimals, to the right if (p.y < 0 || p.y > 4) return 0; // out of bounds vertically // shift placement to make it tighter around the decimal separator float shift = 0; if (p.x > 1) // decimal digits p.x += 1; else if (p.x < 0) // integer digits { p.x += -3; shift = -2; } const int SEP = 4; // separation between characters const int dIndex = floor(p.x / SEP); // the digit index to read float opacity; int digit; GetSymbolAtPositionInFloat(number, dIndex, decimalCount, /*out*/ digit, /*out*/ opacity); const float2 pos = float2(dIndex * SEP + shift, 0); return opacity * DrawDigit(p - pos, digit); } // btw this might not work on all platforms, it might be Y-flipped or whatever! float2 ClipToPixel(float4 clip) { float2 ndc = float2(clip.x, -clip.y) / clip.w; ndc = (ndc + 1) / 2; return ndc * _ScreenParams.xy; } float2 LocalToPixel(float3 locPos) { return ClipToPixel(UnityObjectToClipPos(float4(locPos, 1))); } float2 WorldToPixel(float3 wPos) { return ClipToPixel(UnityWorldToClipPos(float4(wPos, 1))); } float DrawNumberAtLocalPos(float3 pxCoord, float3 localPos, float number, float scale = 2, int decimalCount = 3) { const float2 pxPos = LocalToPixel(localPos); return DrawNumberAtPxPos(pxCoord, pxPos, number, scale, decimalCount); } float DrawNumberAtWorldPos(float3 pxCoord, float3 worldPos, float number, float scale = 2, int decimalCount = 3) { const float2 pxPos = WorldToPixel(worldPos); return DrawNumberAtPxPos(pxCoord, pxPos, number, scale, decimalCount); }