因此,我正在爲超級任天堂等優秀的老模擬器製作一些像素着色器。你有像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