Blend text in a HLSL shader and have it look like native DirectWrite

Related tags

Graphics dwrite-hlsl
Overview

dwrite-hlsl

This project demonstrates how to blend text in a HLSL shader and have it look like native DirectWrite.

License

This project is an extract of Windows Terminal. See LICENSE.

Implemented features

  • Correctly blending pre-rendered glyphs from a texture atlas with RGBA background and foreground colors in a shader and have it look identical to native DirectWrite/Direct2D.
  • Support for grayscale-antialiased Glyphs

Missing features

  • ClearType
    I'll add support for this at a later point in time.
  • Emojis
    Emojis are luckily very simple to draw and I'll add support later:
    • Draw them with grayscale antialiasing (and not ClearType).
    • Don't use linear gamma space (meaning: DWrite_GetRenderParams). Instead call SetTextRenderingParams(nullptr) before using the rendering target, to reset it to the regular, gamma corrected parameters.
    • Do a simple premultiplied alpha blend with the Emoji's RGBA values on your background color in your shader.
  • This demo doesn't actually use a glyph atlas and only shows the "blending" part of the algorithm.

How to use this

  • dwrite.hlsl contains all of the shader functions relevant for grayscale-antialiased alpha blending. DWrite_GetGrayScaleCorrectedAlpha is the entrypoint function that you need to call in your shader.
  • dwrite.cpp contains support functions which are required to fill out the parameters for DWrite_GetGrayScaleCorrectedAlpha.
  • Draw your glyphs with DirectWrite into your texture atlas however you like them. Basically there are 3 ways to do this:
    • ID2D1RenderTarget::DrawTextLayout
      Direct2D provides various different kinds of render targets. It handles font fallback, provides you with metrics, etc. and is simple to use. However it's not particularly configurable, not the most performant solution and uses extra GPU/CPU memory for Direct2D's internal glyph atlas. This demo application uses this approach.

    • Implement your own custom IDWriteTextRenderer
      Personally I'm not sure about the value of this approach. I feel like it's the worst of both worlds, as it still ties you into the Direct2D ecosystem and allows you to only marginally improve performance, while simultaneously being very difficult to implement. I'd not suggest anyone to use this.

    • IDWriteGlyphRunAnalysis::CreateAlphaTexture
      This is the most performant and also most complex approach, but it's what every serious DirectWrite application uses, including libraries like skia. It straight up yields rasterized glyphs and allows you to do your own anti-aliasing. In order to call this function you need to segment and layout your input text yourself, by calling, as far as I know, at a minimum in that order:

      Grayscale antialiasing using IDWriteGlyphRunAnalysis::CreateAlphaTexture requires you to render the glyph at 4 times the actual pixel size in both directions (oversampling). Afterwards you can compute the alpha values of the glyph as a percentage of how many of the 16 oversampled pixels are present for each actual pixel. As we need to create the glyph texture in linear gamma space, the implementation can use a linear gradient for the alpha value. The complexity of calling all the text segmentation/layouting functions however isn't that great. But it's doable in a few hundred lines of code and I plan to add a custom glyph atlas implementation based on that in the future. In the meantime I'm using an approach based on ID2D1RenderTarget::DrawTextLayout myself.

Owner
Leonard Hecker
codeninjawizardhacker. AMA.
Leonard Hecker
My computer graphics playground. Currently has a raytracer implemented with D3D11 compute shader.

Graphics Playground I use this project as my "toy" engine. I'll be implementing various graphics projects in this repository. The code here is not sui

Berk Emre Sarıbaş 4 Aug 26, 2021
Linux/X11 tool for intercepting mouse events and executing commands. Written in Kotlin Native.

XMG XMG (X11 Mouse Grabber) is a Linux/X11 tool for intercepting mouse button press events and triggering actions. It's a way of making use of the ext

Eduardo Fonseca 12 Sep 11, 2021
Single header C library for rendering truetype text to the screen

kc_truetypeassembler.h Single header C library for assembling textured quads for text rendering using a graphics API. It generates a vertices and text

Kevin Chin 16 Dec 3, 2021
Fast C++ implementation with JSI binding of MD5 for React Native

react-native-quick-md5 Brazingly fast C++ implementation with JSI binding of MD5 for React Native. Confirmed that it's 10x faster than using spark-md5

Takuya Matsuyama 35 Nov 16, 2021
Android studio native project template using cross platform raylib graphics library.

rayturbo Android studio native project template using cross platform raylib graphics library. https://www.raylib.com/ This project use Android Studio

Ciapas Linux 7 Nov 17, 2021
Efficiently spawn and move high amounts of objects like bullets for bullet hells, particles and more.

Godot Native Bullets Efficiently spawn and move high amounts of objects like bullets for bullet hells, particles and more. This is a GDNative plugin,

Samuele Zolfanelli 56 Nov 22, 2021
Horde3D is a small 3D rendering and animation engine. It is written in an effort to create an engine being as lightweight and conceptually clean as possible.

Horde3D Horde3D is a 3D rendering engine written in C++ with an effort being as lightweight and conceptually clean as possible. Horde3D requires a ful

Volker Vogelhuber 1.1k Nov 19, 2021
Lightweight and modular C++11 graphics middleware for games and data visualization

Magnum — Lightweight and modular C++11/C++14 graphics middleware for games and data visualization Looking for an open-source library that gives you gr

Vladimír Vondruš 3.7k Dec 4, 2021
ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Lua, Octave, PHP, Python, R, and Ruby.

TinySpline TinySpline is a small, yet powerful library for interpolating, transforming, and querying arbitrary NURBS, B-Splines, and Bézier curves. Th

Marcel Steinbeck 716 Nov 30, 2021
Real-Time SLAM for Monocular, Stereo and RGB-D Cameras, with Loop Detection and Relocalization Capabilities

Real-Time SLAM for Monocular, Stereo and RGB-D Cameras, with Loop Detection and Relocalization Capabilities

Raul Mur-Artal 6.8k Dec 5, 2021
A C++/DirectX 11 implementation of "A Scalable and Production Ready Sky and Atmosphere Rendering Technique"

Atmosphere Renderer A C++/DirectX 11 implementation of "A Scalable and Production Ready Sky and Atmosphere Rendering Technique" Features interactive e

Z Guan 17 Nov 22, 2021
StereoKit is an easy-to-use open source mixed reality library for building HoloLens and VR applications with C# and OpenXR!

StereoKit is an easy-to-use open source mixed reality library for building HoloLens and VR applications with C# and OpenXR! Inspired by libraries like XNA and Processing, StereoKit is meant to be fun to use and easy to develop with, yet still quite capable of creating professional and business ready software.

Nick Klingensmith 308 Nov 29, 2021
FFVideo - an example FFmpeg lib, and wxWidgets Player with video filters and face detection

An example FFmpeg lib, and wxWidgets Player application with video filters and face detection, it is a no-audio video player intended for video experiments and developers learning how to code media applications.

Blake Senftner 17 Nov 30, 2021
Draco is a library for compressing and decompressing 3D geometric meshes and point clouds.

Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.

Google 4.6k Dec 3, 2021
A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

null 311 Dec 5, 2021
Brand new engine with new and QoL features. Grafex is Psych engine with some additions and Better graphics

Friday Night Funkin' - Graphex Engine Credits: Grafex Mod aka Psych Graphic Rework: Xale - Lead Coding, Artist PurpleSnake - Second Coder Psych Engine

Xale 4 Dec 3, 2021
Powerful, easy to use, and portable visualization toolkit for mixed 3D and 2D content

Powerful, easy to use, and portable visualization toolkit for mixed 3D and 2D content

Microsoft 82 Dec 5, 2021
A very simple and light-weight drawing app made with qt and C++.

Blackboard A very simple and light-weight drawing app made with qt and C++. It supports tablet and pen pressure with the help of QTabletEvents. So you

null 1 Nov 15, 2021
The official Open-Asset-Importer-Library Repository. Loads 40+ 3D-file-formats into one unified and clean data structure.

Open Asset Import Library (assimp) A library to import and export various 3d-model-formats including scene-post-processing to generate missing render

Open Asset Import Library 7.3k Dec 4, 2021