summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2023-02-02 01:02:03 -0800
committeryum <yum.food.vr@gmail.com>2023-02-13 14:36:20 -0800
commit7c6894614dcc3ebc5d4c8839b64f4da761b5ccf0 (patch)
tree6232b86b09190fd162aeb67229da359971b2e517
parent2fc3b1b978b6e24814e9de7200865b912108bd34 (diff)
Begin work adding emotes
Done: * Users can add images to Fonts/Emotes/ * The basename of that image ('clueless.png' becomes 'clueless') is the keyword to make the image show up in game. * Fix a bug in the shader where letters on the 2nd texture and later would have UV outside of [0.0, 1.0] Not yet implemented: * transcribed words are encoded using emotes mapping
-rw-r--r--Fonts/Bitmaps/emotes.png.meta116
-rw-r--r--Fonts/Emotes/README.md11
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp34
-rw-r--r--GUI/package.ps11
-rw-r--r--Scripts/emotes.py16
-rw-r--r--Scripts/emotes_v2.py109
-rw-r--r--Scripts/generate_shader.py6
-rw-r--r--Scripts/osc_ctrl.py10
-rw-r--r--Scripts/transcribe.py33
-rw-r--r--Shaders/TaSTT_lighting_template.cginc55
-rw-r--r--Shaders/TaSTT_template.shader2
-rw-r--r--UnityAssets/Materials/TaSTT_Text.mat28
12 files changed, 380 insertions, 41 deletions
diff --git a/Fonts/Bitmaps/emotes.png.meta b/Fonts/Bitmaps/emotes.png.meta
new file mode 100644
index 0000000..c2bc609
--- /dev/null
+++ b/Fonts/Bitmaps/emotes.png.meta
@@ -0,0 +1,116 @@
+fileFormatVersion: 2
+guid: 054057c5bf512e842854e6746e754159
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 11
+ mipmaps:
+ mipMapMode: 1
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 1
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ applyGammaDecoding: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 4096
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 2
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 4096
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 2
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Android
+ maxTextureSize: 4096
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 2
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spritePackingTag:
+ pSDRemoveMatte: 0
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Fonts/Emotes/README.md b/Fonts/Emotes/README.md
new file mode 100644
index 0000000..fb12665
--- /dev/null
+++ b/Fonts/Emotes/README.md
@@ -0,0 +1,11 @@
+To add emotes to the text box, place one or more .png files in this directory.
+The name of the file should be the word you will say in game to make the emote
+appear.
+
+For example,consider the following contents:
+
+ Emotes/smile.png
+ Emotes/cry.png
+
+Saying "smile" would cause the image smile.png to show up on the text box.
+
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp
index c2515e8..72897b7 100644
--- a/GUI/GUI/GUI/PythonWrapper.cpp
+++ b/GUI/GUI/GUI/PythonWrapper.cpp
@@ -11,6 +11,10 @@
using ::Logging::Log;
+namespace {
+ constexpr const char kEmotesPickle[] = "Resources/Fonts/Bitmaps/emotes.map";
+} // namespace
+
class PythonProcess : public wxProcess {
public:
PythonProcess(std::function<void(wxProcess* proc, int ret)>&& exit_callback) : exit_cb_(exit_callback) {
@@ -185,6 +189,7 @@ wxProcess* PythonWrapper::StartApp(
"--window_duration_s", config.window_duration,
"--cpu", config.use_cpu ? "1" : "0",
"--use_builtin", config.use_builtin ? "1" : "0",
+ "--emotes_pickle", kEmotesPickle,
},
std::move(exit_callback));
}
@@ -199,6 +204,7 @@ bool PythonWrapper::GenerateAnimator(
// Python script locations
std::string libunity_path = "Resources/Scripts/libunity.py";
std::string libtastt_path = "Resources/Scripts/libtastt.py";
+ std::string generate_emotes_path = "Resources/Scripts/emotes_v2.py";
std::string generate_params_path = "Resources/Scripts/generate_params.py";
std::string generate_menu_path = "Resources/Scripts/generate_menu.py";
std::string generate_shader_path = "Resources/Scripts/generate_shader.py";
@@ -263,6 +269,34 @@ bool PythonWrapper::GenerateAnimator(
}
}
{
+ Log(out, "Generating emotes... ");
+
+ std::string py_stdout, py_stderr;
+ if (InvokeWithArgs({ generate_emotes_path,
+ "Resources/Fonts/Emotes/",
+ /*board_aspect_ratio=*/ std::to_string(6),
+ /*texture_aspect_ratio=*/ std::to_string(2),
+ "Resources/Fonts/Bitmaps/emotes.png",
+ kEmotesPickle
+ },
+ &py_stdout, &py_stderr)) {
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ Log(out, "\n");
+ }
+ Log(out, py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ Log(out, "\n");
+ }
+ }
+ else {
+ wxLogError("Failed to generate emotes: %s", py_stderr.c_str());
+ Log(out, "failed!\n");
+ return false;
+ }
+ }
+ {
Log(out, "Creating {}\n", tastt_generated_dir_path.string());
std::filesystem::create_directories(tastt_generated_dir_path);
}
diff --git a/GUI/package.ps1 b/GUI/package.ps1
index 96e641e..74fd7c7 100644
--- a/GUI/package.ps1
+++ b/GUI/package.ps1
@@ -62,6 +62,7 @@ mkdir $install_dir/Resources > $null
cp -Recurse ../Animations TaSTT/Resources/Animations
mkdir TaSTT/Resources/Fonts
cp -Recurse ../Fonts/Bitmaps TaSTT/Resources/Fonts/Bitmaps
+cp -Recurse ../Fonts/Emotes TaSTT/Resources/Fonts/Emotes
cp -Recurse ../Images TaSTT/Resources/Images
cp -Recurse Python TaSTT/Resources/Python
cp -Recurse PortableGit TaSTT/Resources/PortableGit
diff --git a/Scripts/emotes.py b/Scripts/emotes.py
index 0a4ed01..6ae0930 100644
--- a/Scripts/emotes.py
+++ b/Scripts/emotes.py
@@ -111,16 +111,28 @@ def addImageToTexture(tex: Image, img_path: str, x: int, y:int):
def parseArgs():
parser = argparse.ArgumentParser()
parser.add_argument("--texture_path", type=str, help="Path to save the generated texture.")
+ parser.add_argument("--rows", type=str, help="The number of rows on the board")
+ parser.add_argument("--cols", type=str, help="The number of columns on the board")
args = parser.parse_args()
- if not args.texture_path:
- args.texture_path = "img_texture.png"
+ if not args.texture_path or not args.rows or not args.cols:
+ print("--texture_path, --rows, --cols required", file=sys.stderr)
+ sys.exit(1)
return args
if __name__ == "__main__":
args = parseArgs()
+ rows = int(args.rows)
+ cols = int(args.cols)
+ # board is this much wider than tall
+ board_aspect_ratio = 2
+ # each cell a square divided into `rows`x`cols` is this much wider than tall
+ cell_aspect_ratio = rows / cols
+ # each cell is this much wider than tall
+ board_cell_aspect_ratio = board_aspect_ratio * cell_aspect_ratio
+
tex = openTexture(args.texture_path)
for i in range(0, len(IMG_TEX_DATA)):
filename = IMG_TEX_DATA[i][0]
diff --git a/Scripts/emotes_v2.py b/Scripts/emotes_v2.py
new file mode 100644
index 0000000..195e116
--- /dev/null
+++ b/Scripts/emotes_v2.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import pickle
+import sys
+
+from math import floor
+from PIL import Image
+from typing import Any, Dict, List, Tuple
+
+# The character range [0x0000, 0xDFFF] is reserved for text.
+# The range [0xE000, infinity) is left over for emotes.
+EMOTES_LETTER_OFFSET = 0xE000
+
+def superimpose_image(base_img: Image, overlay_img: Image, position: Tuple[int, int]) -> Image:
+ base_img.paste(overlay_img, position, overlay_img)
+ return base_img
+
+def i_to_pos(i, sm_wd, sm_ht, big_wd, big_ht) -> Tuple[int, int]:
+ x = i * sm_wd % big_wd
+ row = floor((i * sm_wd) / big_wd)
+ y = row * sm_ht
+ return int(x), int(y)
+
+def get_images_from_directory(directory_path: str) -> List[Tuple[Any, str]]:
+ images = []
+ for filename in os.listdir(directory_path):
+ file_path = os.path.join(directory_path, filename)
+ if os.path.isfile(file_path) and file_path.endswith(".png"):
+ image = Image.open(file_path)
+ name = os.path.basename(filename).split('.')[0]
+ images.append((image, name))
+ return images
+
+def split_resized_image(img, wd: int, ht: int) -> List[Any]:
+ aspect_ratio = img.width / img.height
+ width = int(ht * aspect_ratio)
+ img = img.resize((width, ht))
+
+ split_images = []
+ for i in range(0, img.width, wd):
+ split_image = img.crop((i, 0, i + wd, ht))
+ split_images.append(split_image)
+
+ return split_images
+
+print(i_to_pos(0, 5, 10, 10, 20))
+print(i_to_pos(1, 5, 10, 10, 20))
+print(i_to_pos(2, 5, 10, 10, 20))
+print(i_to_pos(3, 5, 10, 10, 20))
+
+def resize_image_with_aspect_ratio(img: Image, aspect_ratio: float) -> Image:
+ original_width, original_height = img.size
+ new_width = int(original_height * aspect_ratio)
+ new_height = original_height
+ return img.resize((new_width, new_height))
+
+def resize_image_to_height(img: Image, height: int) -> Image:
+ aspect_ratio = img.width / img.height
+ new_width = int(height * aspect_ratio)
+ return img.resize((new_width, height))
+
+class EmotesState:
+ def __init__(self):
+ self.bits = {}
+
+ def load(self, pickle_path):
+ with open(pickle_path, 'rb') as f:
+ self.bits = pickle.load(f)
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument("dir", type=str, help="directory to get images from")
+ parser.add_argument("board_aspect_ratio", help="aspect ratio of a cell in the board")
+ parser.add_argument("texture_aspect_ratio", help="aspect ratio of a cell in the texture")
+ parser.add_argument("tex_path", type=str, help="path to save the texture to")
+ parser.add_argument("pickle_path", type=str, help="path to save the texture index to")
+ args = parser.parse_args()
+
+ directory_path = args.dir
+ board_aspect_ratio = int(args.board_aspect_ratio)
+ texture_aspect_ratio = int(args.texture_aspect_ratio)
+
+ base_img = Image.new("RGBA", (4096, 4096), (0, 0, 0, 0))
+ images_and_filenames = get_images_from_directory(directory_path)
+ i = 0
+ bits = {} # Dict[str, List[int]]
+ for img, filename in images_and_filenames:
+ print(f"Adding {filename}")
+ img = resize_image_with_aspect_ratio(img, board_aspect_ratio)
+ img = resize_image_to_height(img, 1024)
+ img_fragments = split_resized_image(img, int(1024 / texture_aspect_ratio), 1024)
+ img_bits = [] # List[int]
+ for img_fragment in img_fragments:
+ i = i + 1
+ img_pos = i_to_pos(i,
+ 1024 / texture_aspect_ratio, 1024,
+ 4096, 4096)
+ print(f"{img_pos}")
+ superimpose_image(base_img, img_fragment, img_pos)
+ img_bits.append(EMOTES_LETTER_OFFSET + i)
+ emote_name = os.path.basename(filename).split('.')[0]
+ print(f"{emote_name} -> {img_bits}")
+ bits[emote_name] = img_bits
+ base_img.save(args.tex_path)
+ with open(args.pickle_path, 'wb') as f:
+ pickle.dump(bits, f)
+
diff --git a/Scripts/generate_shader.py b/Scripts/generate_shader.py
index 9ff0bc3..cf113ec 100644
--- a/Scripts/generate_shader.py
+++ b/Scripts/generate_shader.py
@@ -64,8 +64,8 @@ def generateCgConstants(nbytes: int, nrows: int, ncols: int, prefix: str = "") -
# case 1:
# ...
#
-# res |= ((int) _Letter_Row00_Col00_Byte0) << (0 * 8);
-# res |= ((int) _Letter_Row00_Col00_Byte1) << (1 * 8);
+# res |= ((int) round(_Letter_Row00_Col00_Byte0)) << (0 * 8);
+# res |= ((int) round(_Letter_Row00_Col00_Byte1)) << (1 * 8);
# continue;
# }
# }
@@ -84,7 +84,7 @@ def generateLetterAccessor(nbytes: int, nrows: int, ncols: int, prefix: str = ""
lines.append(prefix + " case {}:".format(col))
for byte in range(0, nbytes):
param_name = generate_utils.getShaderParamByRowColByte(row, col, byte)
- lines.append(prefix + " res |= ((int) {}) << ({} * 8);".format(param_name, byte))
+ lines.append(prefix + " res |= ((int) round({})) << ({} * 8);".format(param_name, byte))
lines.append(prefix + " return res;")
lines.append(prefix + " default:")
lines.append(prefix + " return 0;")
diff --git a/Scripts/osc_ctrl.py b/Scripts/osc_ctrl.py
index 93b236b..750059f 100644
--- a/Scripts/osc_ctrl.py
+++ b/Scripts/osc_ctrl.py
@@ -1,11 +1,13 @@
#!/usr/bin/env python3
-import argparse
+from emotes_v2 import EmotesState
from generate_utils import config
-import generate_utils
+from math import ceil
from paging import MultiLinePager
from pythonosc import udp_client
-from math import ceil
+
+import argparse
+import generate_utils
import time
# Based on a couple experiments, this seems like about as fast as we can go
@@ -87,7 +89,7 @@ def updateRegion(client, region_idx, letter_encoded):
# Sends one slice of `msg` to the board then returns. Slices are sent
# in FIFO order; e.g., the most recently spoken words are sent last.
# Returns True if done paging, False otherwise.
-def pageMessage(osc_state: OscState, msg: str) -> bool:
+def pageMessage(osc_state: OscState, msg: str, estate: EmotesState) -> bool:
msg_slice, slice_idx = osc_state.pager.getNextSlice(msg)
if slice_idx == -1:
return True
diff --git a/Scripts/transcribe.py b/Scripts/transcribe.py
index ee76a0a..3171336 100644
--- a/Scripts/transcribe.py
+++ b/Scripts/transcribe.py
@@ -1,28 +1,23 @@
#!/usr/bin/env python3
+from datetime import datetime
+from emotes_v2 import EmotesState
+from functools import partial
+from playsound import playsound
+
import argparse
import copy
-from datetime import datetime
import os
import osc_ctrl
-from functools import partial
import generate_utils
-# python3 -m pip install pyaudio
-# License: MIT.
import pyaudio
import numpy as np
-# python3 -m pip install playsound==1.2.2
-# License: MIT.
-from playsound import playsound
import steamvr
import string_matcher
import sys
import threading
import time
import wave
-# python3 -m pip install git+https://github.com/openai/whisper.git
-# python3 -m pip install torch -f https://download.pytorch.org/whl/torch_stable.html
-# License: MIT.
import whisper
class Config:
@@ -303,14 +298,14 @@ def transcribeAudio(audio_state, model, use_cpu: bool):
audio_state.transcribe_no_change_count = 0
audio_state.transcribe_sleep_duration = audio_state.transcribe_sleep_duration_min_s
-def sendAudio(audio_state, use_builtin: bool):
+def sendAudio(audio_state, use_builtin: bool, estate: EmotesState):
while audio_state.run_app == True:
text = audio_state.committed_text + " " + audio_state.text
if use_builtin:
ret = osc_ctrl.pageMessageBuiltin(audio_state.osc_state, text)
time.sleep(1.5)
else:
- ret = osc_ctrl.pageMessage(audio_state.osc_state, text)
+ ret = osc_ctrl.pageMessage(audio_state.osc_state, text, estate)
is_paging = (ret == False)
osc_ctrl.indicatePaging(audio_state.osc_state.client, is_paging)
@@ -393,7 +388,7 @@ def readControllerInput(audio_state, enable_local_beep: bool,
# whisper/__init__.py. Examples: tiny, base, small, medium.
def transcribeLoop(mic: str, language: str, model: str,
enable_local_beep: bool, use_cpu: bool, use_builtin: bool,
- button: str):
+ button: str, estate: EmotesState):
audio_state = getMicStream(mic)
audio_state.language = whisper.tokenizer.TO_LANGUAGE_CODE[language]
@@ -410,7 +405,7 @@ def transcribeLoop(mic: str, language: str, model: str,
transcribe_audio_thd.daemon = True
transcribe_audio_thd.start()
- send_audio_thd = threading.Thread(target = sendAudio, args = [audio_state, use_builtin])
+ send_audio_thd = threading.Thread(target = sendAudio, args = [audio_state, use_builtin, estate])
send_audio_thd.daemon = True
send_audio_thd.start()
@@ -459,6 +454,7 @@ if __name__ == "__main__":
parser.add_argument("--cpu", type=int, help="If set to 1, use CPU instead of GPU")
parser.add_argument("--use_builtin", type=int, help="If set to 1, use the text box built into the game.")
parser.add_argument("--button", type=str, help="The controller button used to start/stop transcription. E.g. \"left joystick\"")
+ parser.add_argument("--emotes_pickle", type=str, help="The path to emotes pickle. See emotes_v2.py for details.")
args = parser.parse_args()
if not args.mic:
@@ -482,6 +478,10 @@ if __name__ == "__main__":
print("--button required", file=sys.stderr)
sys.exit(1)
+ if not args.emotes_pickle:
+ print("--emotes_pickle required", file=sys.stderr)
+ sys.exit(1)
+
if args.window_duration_s:
config.MAX_LENGTH_S = int(args.window_duration_s)
@@ -495,11 +495,14 @@ if __name__ == "__main__":
else:
args.use_builtin = False
+ estate = EmotesState()
+ estate.load(args.emotes_pickle)
+
generate_utils.config.BYTES_PER_CHAR = int(args.bytes_per_char)
generate_utils.config.CHARS_PER_SYNC = int(args.chars_per_sync)
generate_utils.config.BOARD_ROWS = int(args.rows)
generate_utils.config.BOARD_COLS = int(args.cols)
transcribeLoop(args.mic, args.language, args.model, args.enable_local_beep,
- args.cpu, args.use_builtin, args.button)
+ args.cpu, args.use_builtin, args.button, estate)
diff --git a/Shaders/TaSTT_lighting_template.cginc b/Shaders/TaSTT_lighting_template.cginc
index 386a509..15b4e41 100644
--- a/Shaders/TaSTT_lighting_template.cginc
+++ b/Shaders/TaSTT_lighting_template.cginc
@@ -231,7 +231,8 @@ bool InMarginRounding(float2 uv, float2 margin, float rounding, bool interior)
// in the texture being sampled.
float2 GetLetter(float2 uv, int nth_letter,
float texture_cols, float texture_rows,
- float board_cols, float board_rows)
+ float board_cols, float board_rows,
+ float margin)
{
// UV spans from [0,1] to [0,1].
// 'U' is horizontal; cols.
@@ -248,11 +249,14 @@ float2 GetLetter(float2 uv, int nth_letter,
// Avoid rendering pixels right on the edge of the slot. If we were to
// do this, then that value would get stretched due to clamping
// (AddMarginToUV), resulting in long lines on the edge of the display.
- if (CHAR_FRAC_ROW < 0.01 ||
- CHAR_FRAC_COL < 0.01 ||
- CHAR_FRAC_ROW > 0.99 ||
- CHAR_FRAC_COL > 0.99) {
- return float2(0, 0);
+ float lo = margin / 2;
+ float hi = 1.0 - margin / 2;
+ if (margin != 0 &&
+ (CHAR_FRAC_ROW < lo ||
+ CHAR_FRAC_COL < lo ||
+ CHAR_FRAC_ROW > hi ||
+ CHAR_FRAC_COL > hi)) {
+ return float2(-1, -1);
}
float LETTER_COL = fmod(nth_letter, floor(texture_cols));
@@ -576,17 +580,20 @@ fixed4 frag(v2f i) : SV_Target
float texture_cols;
float texture_rows;
float2 letter_uv;
+ bool is_emote = false;
if (letter < 0xE000) {
texture_cols = 128.0;
texture_rows = 64.0;
- letter_uv = GetLetter(uv_with_margin, letter, texture_cols, texture_rows, NCOLS, NROWS);
+ letter_uv = GetLetter(uv_with_margin, letter % 0x2000, texture_cols, texture_rows, NCOLS, NROWS, /*margin=*/0.02);
} else {
+ is_emote = true;
texture_cols = 8.0;
- texture_rows = 8.0;
- letter_uv = GetLetter(uv_with_margin, letter, texture_cols, texture_rows, 8, 4);
+ texture_rows = 4.0;
+ // This will need to be updated if we create multiple emote textures.
+ letter_uv = GetLetter(uv_with_margin, letter % 0x2000, texture_cols, texture_rows, NCOLS, NROWS, /*margin=*/0);
}
- if (letter_uv.x == 0 && letter_uv.y == 0) {
+ if (letter_uv.x == -1 && letter_uv.y == -1) {
discard_text = true;
}
@@ -626,7 +633,17 @@ fixed4 frag(v2f i) : SV_Target
aa_region_x = lerp(0, iddx, aa_region_x / iddx_convex);
aa_region_y = lerp(0, iddy, aa_region_y / iddy_convex);
- float2 cur_letter_uv = letter_uv + float2(aa_region_x, aa_region_y) * 1;
+ //float2 cur_letter_uv = letter_uv + float2(aa_region_x, aa_region_y);
+ float2 cur_letter_uv = letter_uv;
+
+ if (is_emote) {
+ // Emotes are broken up into several pieces and packed tightly. Thus one
+ // emote may wrap around the edge of the texture. Clamping near the edge
+ // of the texture avoids a small line from appearing in the middle of
+ // these textures.
+ float epsilon = 0.002;
+ cur_letter_uv.x = clamp(cur_letter_uv.x, epsilon, 1.0 - epsilon);
+ }
int which_texture = (int) floor(letter / (64 * 128));
[forcecase] switch (which_texture)
@@ -652,9 +669,12 @@ fixed4 frag(v2f i) : SV_Target
case 6:
text += tex2Dgrad(_Font_0xC000_0xDFFF, cur_letter_uv, iddx, iddy);
break;
- default:
+ case 7:
text += tex2Dgrad(_Img_0xE000_0xE03F, cur_letter_uv, iddx, iddy);
break;
+ default:
+ // Return some distinctive pattern that will look like a bug.
+ return fixed4(1, 0, _SinTime[0], 1);
}
}
text /= aa_amount;
@@ -662,9 +682,10 @@ fixed4 frag(v2f i) : SV_Target
// The edges of each letter cell can be slightly grey due to mip maps.
// Detect this and shade it as the background.
fixed3 grey = fixed3(.4,.4,.4);
- if (f3ltf3(text.rgb, grey) || discard_text) {
+ if (f3ltf3(text.rgb, grey) || discard_text || is_emote) {
+ fixed4 bg;
if (BG_Enable) {
- return light(i,
+ bg = light(i,
BG_BaseColor,
BG_NormalMap,
BG_NormalStrength,
@@ -674,8 +695,12 @@ fixed4 frag(v2f i) : SV_Target
BG_Emission_Mask,
BG_Emission_Color);
} else {
- return light(i, Background_Color);
+ bg = light(i, Background_Color);
+ }
+ if (is_emote) {
+ bg.rgb = lerp(bg.rgb, text.rgb, text.w);
}
+ return bg;
} else {
return light(i, Text_Color);
}
diff --git a/Shaders/TaSTT_template.shader b/Shaders/TaSTT_template.shader
index 708300e..e92a1bd 100644
--- a/Shaders/TaSTT_template.shader
+++ b/Shaders/TaSTT_template.shader
@@ -40,7 +40,7 @@
_Font_0x8000_0x9FFF ("_Font 4 (unicode 0x8000 - 0x9FFFF)", 2D) = "white" {}
_Font_0xA000_0xBFFF ("_Font 5 (unicode 0xA000 - 0xBFFFF)", 2D) = "white" {}
_Font_0xC000_0xDFFF ("_Font 6 (unicode 0xC000 - 0xDFFFF)", 2D) = "white" {}
- _Img_0xE000_0xE03F ("_Images 0", 2D) = "white" {}
+ _Img_0xE000_0xE03F ("_Images", 2D) = "white" {}
_TaSTT_Indicator_0("_TaSTT_Indicator_0", float) = 0
_TaSTT_Indicator_1("_TaSTT_Indicator_1", float) = 0
diff --git a/UnityAssets/Materials/TaSTT_Text.mat b/UnityAssets/Materials/TaSTT_Text.mat
index 51bf253..2739a4d 100644
--- a/UnityAssets/Materials/TaSTT_Text.mat
+++ b/UnityAssets/Materials/TaSTT_Text.mat
@@ -19,6 +19,26 @@ Material:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
+ - BG_BaseColor:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - BG_Emission_Mask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - BG_Metallic:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - BG_NormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - BG_Smoothness:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
- Custom_Background:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
@@ -76,7 +96,7 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Img_0xE000_0xE03F:
- m_Texture: {fileID: 0}
+ m_Texture: {fileID: 2800000, guid: 054057c5bf512e842854e6746e754159, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
@@ -96,7 +116,12 @@ Material:
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
+ - AA_Amount: 5
+ - BG_Enable: 0
+ - BG_NormalStrength: 1
+ - BG_Smoothness_Invert: 1
- Emissive: 0.1
+ - Enable_Dithering: 1
- Enable_Margin_Effect_Squares: 0
- Margin_Rounding_Scale: 0.11
- Margin_Scale: 0.06
@@ -510,6 +535,7 @@ Material:
- _UVSec: 0
- _ZWrite: 1
m_Colors:
+ - BG_Emission_Color: {r: 0, g: 0, b: 0, a: 1}
- Background_Color: {r: 0, g: 0, b: 0, a: 1}
- Margin_Color: {r: 1, g: 1, b: 1, a: 1}
- SpecularTint: {r: 1, g: 1, b: 1, a: 1}