2017-03-05 179 views
0

我正在研究一個WebGL OpenGL ES項目,該項目將我的場景渲染爲紋理,然後使用該紋理渲染到窗口。當渲染爲FBO紋理時紋理座標稍微偏移

我注意到這會導致紋理邊緣出現奇怪的閃爍。當我將項目恢復爲直接渲染到窗口時,閃爍消失。

FBO被設置爲與窗口相同的大小,並且紋理被繪製到像素的窗口像素。

是什麼導致這種情況發生?它可以修復嗎?我在FBO紋理上使用GL_NEAREST,在所有其他紋理上使用GL_LINEAR。我寧願不使用GL_CLAMP_TO_EDGE,因爲這會導致其他問題。

[render to screen] render to fbo

幀緩衝區創造

/* Returns true if a framebuffer object is created */ 
Display.prototype.createFramebuffer = function(name) { 
    var gl = this.gl; // Sanity Save 

    var size = 1024; 

    var fb = gl.createFramebuffer(); 
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 
    fb.width = size; 
    fb.height = size; 

    var tex = gl.createTexture(); 
    gl.bindTexture(gl.TEXTURE_2D, tex); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, fb.width, fb.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 

    var rb = gl.createRenderbuffer(); 
    gl.bindRenderbuffer(gl.RENDERBUFFER, rb); 
    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, fb.width, fb.height); 
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); 
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb); 

    if(gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { return false; } 

    this.fbo[name] = {fb: fb, rb: rb, tex: tex}; 

    gl.bindTexture(gl.TEXTURE_2D, null); 
    gl.bindRenderbuffer(gl.RENDERBUFFER, null); 
    gl.bindFramebuffer(gl.FRAMEBUFFER, null); 

    return true; 
}; 

之前繪製現場

/* Draw Geometry */ 
gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo.world.fb); // Enable world framebuffer 
gl.viewport(0, 0, this.window.width, this.window.height); // Resize to canvas 
gl.clearColor(0.5, 0.5, 0.5, 1.0); // Opaque grey backdrop 
+0

您的FBO設置如何?與屏幕尺寸和格式相同?你在使用OpenGL還是OpenGL-es?顯示相關的代碼。 – BDL

+0

@BDL添加了設置代碼。它與屏幕大小和格式相同。這就是WebGL使用的OpenGL ES。 –

+0

所以它實際上是WebGL?所有三個版本,Desktop-OpenGL,Op​​enGL-es和WebGL都有自己的限制和限制。用正確的標記問題可以確保您不會得到不適用於您的環境的答案。 – BDL

回答

0

在正確的方向推(和大量的T後rial和錯誤)我找出了問題。

發生這種情況的原因是因爲渲染到FBO紋理時禁用了硬件抗鋸齒功能。爲了解決它,你需要實現你自己的AA。

爲了解決這個問題,我嘗試了一個粗糙的MSAA後處理着色器,並將我的FBO渲染放大到2倍的窗口分辨率,並將閃爍降低到幾乎不明顯的程度。

FXAA可能是另一個很好的解決方案,但我無法親自爲它工作。

如果還有更好的方法可以讓我知道!

+1

我會說另一種方式。問題是,無論你在做什麼都是反敏感的。我認爲我會盡力使它不是抗鋸齒敏感的,而不是如何對FBO進行抗鋸齒。 – gman

+0

@gman從我已閱讀的內容WebGL在渲染到FBO紋理時不支持抗鋸齒。這些信息的一些來源有些老舊(1 - 2年)。如果你能找到一些可靠的參考,我很樂意找到更好的方法來處理這個問題。我不喜歡使用我自己的AA方法,因爲它們效率低下。我也非常感謝幫助。我覺得我經常在這裏完全忽略它。 –