C# 双线性插值-DirectX与GDI+;
我有一个C#应用程序,我已经为它编写了GDI+代码,它使用位图/TextureBrush渲染来呈现2D图像,可以应用各种图像处理功能。此代码是应用程序中的一个新路径,模拟现有DX9代码,它们共享一个公共库来执行所有向量和矩阵(例如ViewToWorld/WorldToView)操作。我的测试台由DX9输出图像组成,我将其与新GDI+代码的输出进行比较 一个简单的测试用例,渲染到与位图尺寸匹配的视口(即没有缩放或平移)确实匹配像素完美(没有二进制差异)-但一旦图像放大(放大),我会得到5-10%像素的微小差异。差值的大小为1(偶尔为2)/256。我怀疑这是由于插值差异造成的 问题:对于DX9正交投影(和标识世界空间),相机垂直并以纹理四边形为中心,在使用设置时,是否有理由期望生成与GDI+TextureBrush填充矩形/多边形相同的输出 对于这种(放大)情况,DX9代码使用的是(MinFilter,MipFilter设置类似):C# 双线性插值-DirectX与GDI+;,c#,image-processing,3d,directx,gdi+,C#,Image Processing,3d,Directx,Gdi+,我有一个C#应用程序,我已经为它编写了GDI+代码,它使用位图/TextureBrush渲染来呈现2D图像,可以应用各种图像处理功能。此代码是应用程序中的一个新路径,模拟现有DX9代码,它们共享一个公共库来执行所有向量和矩阵(例如ViewToWorld/WorldToView)操作。我的测试台由DX9输出图像组成,我将其与新GDI+代码的输出进行比较 一个简单的测试用例,渲染到与位图尺寸匹配的视口(即没有缩放或平移)确实匹配像素完美(没有二进制差异)-但一旦图像放大(放大),我会得到5-10%像
Device.SetSamplerState(0,SamplerStageStates.MagFilter,(int)TextureFilter.Linear)代码>
GDI+路径正在使用:
g.InterpolationMode=InterpolationMode.双线性代码>
我原以为“双线性插值”是一个相当具体的过滤器定义,但后来我注意到GDI+中还有另一个选项用于“高质量双线性”(我已经尝试过了,没有任何区别——考虑到“为收缩添加预滤波”的描述,这是有意义的)
后续问题:在DirectX和GDI+之间期望像素完美的输出匹配是否合理(假设传入的所有外部坐标相等)?若否,原因为何
澄清:我使用的图像是不透明的灰度(R=G=B,A=1),使用Format32bppPArgb
最后,我还可以使用其他一些API(Direct2D、WPF、GDI等)——这个问题通常适用于比较任意两个API中“等效”双线性插值输出图像的输出。谢谢 DirectX主要在GPU中运行,DX9可能运行着色器。GDI+在完全不同的算法上运行。我认为,期望两者能够提供完全匹配的像素输出是不合理的
我希望DX9比GDI+有更好的质量,这是对旧GDI的一步改进,但不是很多。长期以来,人们一直认为GDI+在抗锯齿线以及在图像缩放中保持质量方面存在问题(这似乎是您的问题)。为了在质量上与最新一代GPU纹理处理类似,您需要转到WPF图形。这提供了类似于DX的质量
WPF还使用GPU(如果可用)并返回到软件渲染(如果没有GPU),因此GPU和软件渲染之间的输出相当接近
编辑:虽然这已经被选为答案,但这只是一个早期的解释,并没有真正解决真正的原因。读者可以参考对问题和答案的评论中列出的讨论 你为什么假设他们使用相同的公式
即使它们使用相同的公式,并且您接受实现是不同的,您会期望输出是相同的吗
一天结束时,代码被设计用于感知,而不是数学上精确的感知。如果你愿意的话,你可以通过CUDA得到这个
如果你得到的是像素完美匹配,我会非常惊讶,而不是惊讶于你得到了不同的结果
它们代表颜色的方式是不同的。。。我知道nvidia使用浮点数(可能是双精度)来表示颜色,而GDI使用int表示颜色
在DX9着色器2.0中,当颜色的实现从int切换到24位和32位浮点时出现
尝试比较ati/amd渲染和nvidia渲染,您可以清楚地看到颜色非常不同。
我第一次注意到这是在地震2。。。这两张卡之间的差异是惊人的——当然,这是由于很多原因造成的,其中最不重要的是它们的bilinier interp实现
编辑:在我回答后,关于规范是如何制定的信息。不管怎样,我认为用来存储它的数据类型是不同的,不管你怎么指定它。此外,float的实现可能会有所不同。我可能错了,但我很确定c#实现的float与nvidia使用的c编译器不同。(假设GDI+不只是将浮点值转换为等效的int…)
即使我在这一点上错了,我通常也会认为一个算法的两个不同实现是相同的,这是一个例外。它们被视为速度,因此,视错觉的差异将直接转化为图像质量的差异,因为这种速度将来自不同的捷径/近似方法。有两种可能的四舍五入差异。第一个是显而易见的,当RGB值被计算为任意一侧值的一部分时。第二个更微妙,当计算确定两点之间的分数时使用的比率
事实上,如果两种不同的算法实现是完全相同的,我会非常惊讶,有那么多地方会出现+/-1的差异。如果没有这两种方法的具体实现细节,就不可能比这更精确。我不明白。当使用插值时,如何期望像素完美值?插值的目的是改变像素值。如果你的观点是DX和GDI+的插值方式不同:不,它们没有。不同