2015-10-14 97 views

回答

2

有三种方式来处理在Direct3D 11灰阶的纹理:

选项(1):您可以使用RGB格式和复制的通道。例如,您可以使用DXGI_R8G8B8A8_UNORM并将R,G,B设置为单个单色通道,将A设置为全部不透明(0xFF)。您可以用同样的方法处理Monochrome + Alpha(2通道)数据。

这种转换通过加载库DirectXTex亮度.DDS格式(D3DFMT_L8D3DFMT_L8A8),并与-xlum开关texconv命令行工具当支持。

这使纹理内存大4倍,但很容易集成使用标准着色器。

选项(2):您使用DXGI_FORMAT_R8_UNORM作为格式将单色纹理保留为单个通道。然后使用自定义着色器在运行时将红色通道复制到RGB。

这其实是你链接的教程博客帖子是这样做的:

///////// PIXEL SHADER 
float4 main(float2 uv : TEXCOORD0) : SV_Target0 
{ 
    return float4(Decal.Sample(Bilinear, uv).rrr, 1.f); 
} 

对于单色+阿尔法(2声道),你会使用DXGI_FORMAT_R8G8_UNORM,然后你的自定义着色器将使用.rrrg为调酒。

选项(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 

然后将所得纹理渲染时使用一个标准的α混合着色器在DirectX Tool KitMakeSpriteFont工具实现。由于每个像素使用1个字节,因此与使用DXGI_FORMAT_R8_UNORM时的大小实际上是相同的。

该技术不适用于双通道数据,但对alpha混合单色图像(如字体字形)非常适用。

+0

感谢您的详细解释查克!选项#2更符合我所需要的内容。我认为DXGI_FORMAT_R8_UNORM是正确的格式,但不确定。我还需要稍微更新一下像素着色器,以正确调整RGB。 –