D3D:硬件 mip 线性混合不同于着色器线性混合
D3D : hardware mip linear blending is different from shader linear blending
我有一个 d3d 应用程序,它在全屏四像素着色器中渲染 mip 映射的立方体贴图。
我偶然发现了一个奇怪的行为,并编写了以下测试来说明这个问题。
此着色器输出硬件 mip 贴图过滤与 HLSL 等效项之间的绝对差异。
TextureCube Tex_EnvMap : register(ps, t0);
SamplerState Sampler_EnvMap : register(ps, s0);
void FragmentMain(in SFragmentInput fInput, out SFragmentOutput fOutput)
{
// ...
// Not shown:
// Mip is an uniform set by the application
// dir is the sampling direction setup from pixel coord.
// ...
float fl = floor(Mip);
float fr = frac(Mip) ;
float3 c0 = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, fl).rgb;
float3 c1 = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, fl + 1.).rgb;
float3 c = lerp(c0, c1, fr);
float3 cref = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, Mip).rgb;
fOutput.outColor = float4 (abs(c-cref), 1);
}
在一台计算机上,此测试在所有 mip 值 (0 - 10) 上呈现黑色,这是预期的。基本应用程序(立方体贴图的显示)在所有 mip 值上具有感知线性混合。
在另一台计算机上,测试在整数 mips 上为黑色(很明显),否则呈现为 this(两种过滤方式明显不同)。基础应用程序有一个感知上更像阶梯的混合,但它仍然有一些混合。就好像 mip 的小数部分是平滑的。
出现问题的机器上的像素捕获显示我的资源的预期值:
Sampler:
Filter ANISOTROPIC
AddressU CLAMP
AddressV CLAMP
AddressW CLAMP
MipLODBias 0.00000f
MaxAnisotropy 16
ComparisonFunc 0
BorderColor
MinLOD 0.00000f
MaxLOD 10.0000f
Image:
Format: R16G16B16A16_FLOAT
Dimensions: 1024⨯1024
# of Mip Levels: 11
Sample Count: 1
Dimensions: 1024⨯1024
Mip Levels: 0-10
Array Slices: 0-5
ResourceMinLODClamp: 0
- 什么会导致这种情况?我正在寻找我的应用程序设置的一些与过滤相关的参数,这些参数可以解释着色器内过滤和 d3d 采样器过滤之间的差异,例如各向异性过滤(但这不是候选对象,因为我使用显式 LOD 采样)。然后找出为什么我的应用程序在 2 个硬件上设置不同应该不会太难。
- 我认为这不是驱动程序问题,但我不是这方面的专家。我使用了一些更高级别的渲染 API 界面,所以我已经用 OGL 或 vulkan 做了同样的测试,问题也出现了。
非常感谢! :-)
我在写 "but anisotropic filtering is not a candidate as I use explicit LOD sampling)"
。
事实证明,这个说法是错误的。据我了解,各向异性过滤不应影响使用 textureLOD 进行的采样,但是,似乎在某些实现中会影响,例如:https://forum.unity.com/threads/tex2dlod-and-anisotropic-filtering.585955/ 我仍然很好奇为什么会这样,希望能有更多参考。
将采样器设置为不使用各向异性过滤解决了这个问题。
我有一个 d3d 应用程序,它在全屏四像素着色器中渲染 mip 映射的立方体贴图。 我偶然发现了一个奇怪的行为,并编写了以下测试来说明这个问题。
此着色器输出硬件 mip 贴图过滤与 HLSL 等效项之间的绝对差异。
TextureCube Tex_EnvMap : register(ps, t0);
SamplerState Sampler_EnvMap : register(ps, s0);
void FragmentMain(in SFragmentInput fInput, out SFragmentOutput fOutput)
{
// ...
// Not shown:
// Mip is an uniform set by the application
// dir is the sampling direction setup from pixel coord.
// ...
float fl = floor(Mip);
float fr = frac(Mip) ;
float3 c0 = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, fl).rgb;
float3 c1 = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, fl + 1.).rgb;
float3 c = lerp(c0, c1, fr);
float3 cref = Tex_EnvMap.SampleLevel(Sampler_EnvMap, dir, Mip).rgb;
fOutput.outColor = float4 (abs(c-cref), 1);
}
在一台计算机上,此测试在所有 mip 值 (0 - 10) 上呈现黑色,这是预期的。基本应用程序(立方体贴图的显示)在所有 mip 值上具有感知线性混合。
在另一台计算机上,测试在整数 mips 上为黑色(很明显),否则呈现为 this(两种过滤方式明显不同)。基础应用程序有一个感知上更像阶梯的混合,但它仍然有一些混合。就好像 mip 的小数部分是平滑的。
出现问题的机器上的像素捕获显示我的资源的预期值:
Sampler:
Filter ANISOTROPIC
AddressU CLAMP
AddressV CLAMP
AddressW CLAMP
MipLODBias 0.00000f
MaxAnisotropy 16
ComparisonFunc 0
BorderColor
MinLOD 0.00000f
MaxLOD 10.0000f
Image:
Format: R16G16B16A16_FLOAT
Dimensions: 1024⨯1024
# of Mip Levels: 11
Sample Count: 1
Dimensions: 1024⨯1024
Mip Levels: 0-10
Array Slices: 0-5
ResourceMinLODClamp: 0
- 什么会导致这种情况?我正在寻找我的应用程序设置的一些与过滤相关的参数,这些参数可以解释着色器内过滤和 d3d 采样器过滤之间的差异,例如各向异性过滤(但这不是候选对象,因为我使用显式 LOD 采样)。然后找出为什么我的应用程序在 2 个硬件上设置不同应该不会太难。
- 我认为这不是驱动程序问题,但我不是这方面的专家。我使用了一些更高级别的渲染 API 界面,所以我已经用 OGL 或 vulkan 做了同样的测试,问题也出现了。
非常感谢! :-)
我在写 "but anisotropic filtering is not a candidate as I use explicit LOD sampling)"
。
事实证明,这个说法是错误的。据我了解,各向异性过滤不应影响使用 textureLOD 进行的采样,但是,似乎在某些实现中会影响,例如:https://forum.unity.com/threads/tex2dlod-and-anisotropic-filtering.585955/ 我仍然很好奇为什么会这样,希望能有更多参考。
将采样器设置为不使用各向异性过滤解决了这个问题。