2011-02-15 89 views
3

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

有一些方法,以確保我們能夠抓住從我們所期望的像素的顏色數據,而不是一個不同?我相信會發生這個問題,因爲我們可能從兩個像素之間的座標查詢像素(如果有意義的話)。希望有一些內置的函數能夠被我忽略的這些着色語言。

回答

4

當然,在OpenGL中有幾種方法:

  • 內的着色器,使用texelFetch功能做了紋理拾取,使用整數非標準化的座標。可用於GL_EXT_gpu_shader4擴展或OpenGL 3.0。
  • 使用紋理矩形(GL_ARB_texture_rectangle,OpenGL 3.2),此紋理目標使用未標準化的座標,但不允許使用mipmap並限制某些自動換行模式。

非標準化座標是你想要的,他們是在[0,0]×[W,H]範圍/

+0

我碰到同樣的問題邁斯特爾沒有,但我工作的OpenGL ES 2.0。任何想法如何在該環境下做到這一點? – 2012-03-10 11:19:48