我有一个纹理图集,我是从一组uint中生成的。在我的像素着色器中从中采样,颜色正确显示。这是相关的HLSL:
Texture2D textureAtlas : register(t8);
SamplerState smoothSampler : register(s9)
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
}
struct PS_OUTPUT
{
float4 Color : SV_TARGET0;
float Depth : SV_DEPTH0;
}
PS_OUTPUT PixelShader
{
// among other things, u and v are calculated here
output.Color = textureAtlas.Sample(smoothSampler, float2(u,v));
}
这很有效。通过颜色处理,我扩展了纹理图集以包含深度信息。我想要的只有几千个深度值,低于24位(我的深度缓冲区是24位宽+ 8位模板)。输入深度值是uints,就像颜色一样,当然在深度情况下,值将分布在四个颜色通道上,并且在着色器中我想要一个介于0和1之间的浮点数,因此需要从样本中计算出来。这是附加的像素着色器代码:
// u and v are recalculated for the depth portion of the texture atlas
float4 depthSample = textureAtlas.Sample(smoothSampler, float2(u,v));
float depthValue =
(depthSample.b * 65536.0 +
depthSample.g * 256.0 +
depthSample.r)
/ 65793.003921568627450980392156863;
output.Depth = depthValue;
这里的长常数是16777216/255,它应该将整个uint范围映射到unorm。
现在,当我生成纹理时,如果我将深度值约束到0..2048的范围,则输出深度是正确的。但是,如果我允许范围的上限增加(即使只是通过获取输入值并执行左移16),输出深度将略微偏离。不是很多,只有+/- 0.002,但它足以使输出看起来很糟糕。
有人可以在这里发现我的错误吗?或者,更一般地说,有没有更好的方法来打包和解压缩纹理?
我正在着色模型4级9_3和C ++ 11中工作。