2011-12-09 180 views
3

我正在嘗試實現抗鋸齒像素渲染。我的基本想法是使4個像素,而不是1,並給每一個「真實」的像素基於其距離的權重,以「虛擬」像素:抗鋸齒像素渲染

void put_aa_pixel(double x, double y) 
{ 
    int x0 = int(x); 
    int x1 = x0 + 1; 
    int y0 = int(y); 
    int y1 = y0 + 1; 

    double weight_x1 = x - x0; 
    double weight_x0 = 1 - weight_x1; 
    double weight_y1 = y - y0; 
    double weight_y0 = 1 - weight_x1; 

    put_pixel(x0, y0, int((weight_x0 * weight_y0) * 255)); 
    put_pixel(x1, y0, int((weight_x1 * weight_y0) * 255)); 
    put_pixel(x0, y1, int((weight_x0 * weight_y1) * 255)); 
    put_pixel(x1, y1, int((weight_x1 * weight_y1) * 255)); 
} 

乘以x和y的權重給我的重疊區域每個真實像素內的虛擬像素。我天真地認爲這會給我一個完美的抗鋸齒效果,但是我的測試程序裏面的移動像素只是顯示了一個可笑的閃爍。它看起來比沒有任何抗鋸齒的簡單像素更糟糕。

然而,當我從乘法相加開關,它看起來要好得多:

put_pixel(x0, y0, int((weight_x0 + weight_y0) * 127.5)); 
    put_pixel(x1, y0, int((weight_x1 + weight_y0) * 127.5)); 
    put_pixel(x0, y1, int((weight_x0 + weight_y1) * 127.5)); 
    put_pixel(x1, y1, int((weight_x1 + weight_y1) * 127.5)); 

添加砝碼似乎並不具有任何幾何意義。那麼爲什麼這會更好?第一個版本有什麼問題?還有更好的方法嗎?

+2

想知道,爲什麼不使用像OpenGL這樣的圖形庫來爲你做這一切? –

+5

@Matt:我想知道東西是如何工作的) – fredoverflow

+2

直觀地說:您的x和y權重表示從虛擬像素到真實像素沿着軸的距離。所以,實際距離是sqrt(w_x^2 + w_y^2)。解釋爲什麼總和更好 - 它比乘法更接近這種形式。 – lapk

回答

3

有潛伏在我的代碼了一年半的錯誤:

double weight_x1 = x - x0; 
double weight_x0 = 1 - weight_x1; 
double weight_y1 = y - y0; 
double weight_y0 = 1 - weight_x1; // BUG 

你能看到錯誤?是的,這是一個經典的複製和粘貼錯誤:

double weight_y0 = 1 - weight_y1; // FIXED 

修復bug後,原來的乘法方法看起來很不錯。

4

按照要求:)

直觀:你的X和Y的重量快遞虛擬到真實像素沿軸的距離。所以,實際距離是sqrt(w_x^2 + w_y^2)。解釋爲什麼總和更好 - 它比乘法更接近這種形式。