因此,我正在为超级任天堂等优秀的老模拟器制作一些像素着色器。你有像HQnx,2xSaI等经典算法,它们肯定是写在CPU上运行的,并且在传输到屏幕之前被精确缩放到两倍。移动到GPU片段着色器,这些算法可以基本上免费完成。我正在使用OpenGL和Cg/GLSL,但这个问题也应该适用于Direct3D/HLSL编码器。GPU着色器的像素缩放算法问题
主要问题是这些算法使用一些算法与相邻像素混合来决定颜色。但是,我发现这个概念在着色语言中非常困难。通常在片段着色器中,您可以获得浮点纹理坐标,通常可以使用GL_LINEAR作为纹理过滤器来进行纹理查找。大多数像素着色器使用GL_NEAREST,并自行进行平滑处理。
如果我想查找确切的邻居像素,就会出现问题。我已经看到了一些实现,但他们偶尔会在屏幕上造成文物。可能是由于发生浮点不准确。我发现当使用两次幂次大小的纹理时,大部分工件都会消失,这进一步加强了我相信存在浮点错误的可能性。这里是CG样品片段着色器显示的问题:
struct output
{
float4 color : COLOR;
};
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
};
struct deltas
{
float2 UL, UR, DL, DR;
};
output main_fragment (float2 tex : TEXCOORD0, uniform input IN, uniform sampler2D s_p : TEXUNIT0)
{
float2 texsize = IN.texture_size;
float dx = pow(texsize.x, -1.0) * 0.25;
float dy = pow(texsize.y, -1.0) * 0.25;
float3 dt = float3(1.0, 1.0, 1.0);
deltas VAR = {
tex + float2(-dx, -dy),
tex + float2(dx, -dy),
tex + float2(-dx, dy),
tex + float2(dx, dy)
};
float3 c00 = tex2D(s_p, VAR.UL).xyz;
float3 c20 = tex2D(s_p, VAR.UR).xyz;
float3 c02 = tex2D(s_p, VAR.DL).xyz;
float3 c22 = tex2D(s_p, VAR.DR).xyz;
float m1=dot(abs(c00-c22),dt)+0.001;
float m2=dot(abs(c02-c20),dt)+0.001;
output OUT;
OUT.color = float4((m1*(c02+c20)+m2*(c22+c00))/(2.0*(m1+m2)),1.0);
return OUT;
}
有一些方法,以确保我们能够抓住从我们所期望的像素的颜色数据,而不是一个不同?我相信会发生这个问题,因为我们可能从两个像素之间的坐标查询像素(如果有意义的话)。希望有一些内置的函数能够被我忽略的这些着色语言。
我碰到同样的问题迈斯特尔没有,但我工作的OpenGL ES 2.0。任何想法如何在该环境下做到这一点? – 2012-03-10 11:19:48