DirectX 11 和 FreeType
DirectX 11 and FreeType
有没有人将 FreeType 与 DirectX 11 集成用于字体渲染?我似乎找到的唯一文章是 DirectX 11 Font Rendering。我似乎无法匹配正确的 DXGI_FORMAT 来渲染 FreeType 为字形创建的灰度位图。
Direct3D 11 中处理灰度纹理的三种方法:
选项 (1):您可以使用 RGB 格式并复制通道。例如,您可以使用 DXGI_R8G8B8A8_UNORM
并将 R、G、B 设置为单个单色通道,将 A 设置为全不透明 (0xFF)。您可以用同样的方式处理单色 + Alpha(2 通道)数据。
This conversion is supported when loading .DDS
luminance formats (D3DFMT_L8
, D3DFMT_L8A8
) by DirectXTex library and the texconv command-line tool with the -xlum
switch.
这使得纹理在内存中最多增加 4 倍,但可以使用标准着色器轻松集成。
选项 (2):使用 DXGI_FORMAT_R8_UNORM
作为格式,将单色纹理保持为单个通道。然后使用自定义着色器进行渲染,该着色器在运行时将红色通道复制到 RGB。
这实际上是您链接到的教程博客 post 正在做的事情:
///////// PIXEL SHADER
float4 main(float2 uv : TEXCOORD0) : SV_Target0
{
return float4(Decal.Sample(Bilinear, uv).rrr, 1.f);
}
对于单色 + Alpha(2 通道),您将使用 DXGI_FORMAT_R8G8_UNORM
,然后您的自定义着色器将使用 .rrrg
作为 swizzle。
选项(3):可以使用自定义编码器将单色数据压缩为DXGI_FORMAT_BC2
格式。这是在使用 /TextureFormat:CompressedMono
时在 DirectX Tool Kit's MakeSpriteFont 工具中实现的
// CompressBlock (16 pixels (4x4 block) stored as 16 bytes)
long alphaBits = 0;
int rgbBits = 0;
int pixelCount = 0;
for (int y = 0; y < 4; y++)
{
for (int x = 0; x < 4; x++)
{
long alpha;
int rgb;
// This is the single monochrome channel
int value = bitmapData[blockX + x, blockY + y];
if (options.NoPremultiply)
{
// If we are not premultiplied, RGB is always white and we have 4 bit alpha.
alpha = value >> 4;
rgb = 0;
}
else
{
// For premultiplied encoding, quantize the source value to 2 bit precision.
if (value < 256 / 6)
{
alpha = 0;
rgb = 1;
}
else if (value < 256 / 2)
{
alpha = 5;
rgb = 3;
}
else if (value < 256 * 5 / 6)
{
alpha = 10;
rgb = 2;
}
else
{
alpha = 15;
rgb = 0;
}
}
// Add this pixel to the alpha and RGB bit masks.
alphaBits |= alpha << (pixelCount * 4);
rgbBits |= rgb << (pixelCount * 2);
pixelCount++;
}
}
// The resulting BC2 block is:
// uint64_t = alphaBits
// uint16_t = 0xFFFF
// uint16_t = 0x0
// uint32_t = rgbBits
然后使用标准的 alpha 混合着色器渲染生成的纹理。由于它每个像素使用 1 个字节,因此这实际上与使用 DXGI_FORMAT_R8_UNORM
.
时的大小相同
此技术不适用于 2 通道数据,但适用于 alpha 混合单色图像,如字体字形。
有没有人将 FreeType 与 DirectX 11 集成用于字体渲染?我似乎找到的唯一文章是 DirectX 11 Font Rendering。我似乎无法匹配正确的 DXGI_FORMAT 来渲染 FreeType 为字形创建的灰度位图。
Direct3D 11 中处理灰度纹理的三种方法:
选项 (1):您可以使用 RGB 格式并复制通道。例如,您可以使用 DXGI_R8G8B8A8_UNORM
并将 R、G、B 设置为单个单色通道,将 A 设置为全不透明 (0xFF)。您可以用同样的方式处理单色 + Alpha(2 通道)数据。
This conversion is supported when loading
.DDS
luminance formats (D3DFMT_L8
,D3DFMT_L8A8
) by DirectXTex library and the texconv command-line tool with the-xlum
switch.
这使得纹理在内存中最多增加 4 倍,但可以使用标准着色器轻松集成。
选项 (2):使用 DXGI_FORMAT_R8_UNORM
作为格式,将单色纹理保持为单个通道。然后使用自定义着色器进行渲染,该着色器在运行时将红色通道复制到 RGB。
这实际上是您链接到的教程博客 post 正在做的事情:
///////// PIXEL SHADER
float4 main(float2 uv : TEXCOORD0) : SV_Target0
{
return float4(Decal.Sample(Bilinear, uv).rrr, 1.f);
}
对于单色 + Alpha(2 通道),您将使用 DXGI_FORMAT_R8G8_UNORM
,然后您的自定义着色器将使用 .rrrg
作为 swizzle。
选项(3):可以使用自定义编码器将单色数据压缩为DXGI_FORMAT_BC2
格式。这是在使用 /TextureFormat:CompressedMono
// CompressBlock (16 pixels (4x4 block) stored as 16 bytes)
long alphaBits = 0;
int rgbBits = 0;
int pixelCount = 0;
for (int y = 0; y < 4; y++)
{
for (int x = 0; x < 4; x++)
{
long alpha;
int rgb;
// This is the single monochrome channel
int value = bitmapData[blockX + x, blockY + y];
if (options.NoPremultiply)
{
// If we are not premultiplied, RGB is always white and we have 4 bit alpha.
alpha = value >> 4;
rgb = 0;
}
else
{
// For premultiplied encoding, quantize the source value to 2 bit precision.
if (value < 256 / 6)
{
alpha = 0;
rgb = 1;
}
else if (value < 256 / 2)
{
alpha = 5;
rgb = 3;
}
else if (value < 256 * 5 / 6)
{
alpha = 10;
rgb = 2;
}
else
{
alpha = 15;
rgb = 0;
}
}
// Add this pixel to the alpha and RGB bit masks.
alphaBits |= alpha << (pixelCount * 4);
rgbBits |= rgb << (pixelCount * 2);
pixelCount++;
}
}
// The resulting BC2 block is:
// uint64_t = alphaBits
// uint16_t = 0xFFFF
// uint16_t = 0x0
// uint32_t = rgbBits
然后使用标准的 alpha 混合着色器渲染生成的纹理。由于它每个像素使用 1 个字节,因此这实际上与使用 DXGI_FORMAT_R8_UNORM
.
此技术不适用于 2 通道数据,但适用于 alpha 混合单色图像,如字体字形。