2015-12-14 18 views
4

我在某些OSX機器上看到了一個非常奇怪的問題,其中我的WebGL程序似乎在使用錯誤的紋理內容進行繪製。在所有瀏覽器中使用錯誤紋理的OSX上的WebGL

我有一個sprite批處理設置,我將一組sprite quads緩衝到一個繪製調用中。我還使用多紋理來進一步減少繪製調用的次數,在同一個繪製調用中繪製幾個紋理的精靈。

每個頂點具有以下數據:

// 16 bytes 
float x; 
float y; 
float u; 
float v; 

// 16 bytes 
float texture_offset_x; 
float texture_offset_y; 
float texture_scale_width; 
float texture_scale_height; 

// 24 bytes 
float t0; 
float t1; 
float t2; 
float t3; 
float t4; 
float t5; 

// 8 bytes 
float width_scale; 
float height_scale; 

// 4 bytes 
unsigned byte r; 
unsigned byte g; 
unsigned byte b; 
unsigned byte a; 

// Texture sampler index 
float texture_index; 

而片段着色器結合了抽獎電話是這樣的:

"#version 100", 
    "", 
    "uniform lowp sampler2D sampler0;", 
    "uniform lowp sampler2D sampler1;", 
    "uniform lowp sampler2D sampler2;", 
    "uniform lowp sampler2D sampler3;", 
    "uniform lowp sampler2D sampler4;", 
    "uniform lowp sampler2D sampler5;", 
    "uniform lowp sampler2D sampler6;", 
    "uniform lowp sampler2D sampler7;", 
    "", 
    "varying mediump vec2 vTextureCoord;", 
    "varying lowp vec4 vTintColor;", 
    "varying lowp float vTextureIndex;", 
    "", 
    "void main(void) {", 
    " lowp vec4 fragColors[8];", 
    " fragColors[0] = texture2D(sampler0, vTextureCoord);", 
    " fragColors[1] = texture2D(sampler1, vTextureCoord);", 
    " fragColors[2] = texture2D(sampler2, vTextureCoord);", 
    " fragColors[3] = texture2D(sampler3, vTextureCoord);", 
    " fragColors[4] = texture2D(sampler4, vTextureCoord);", 
    " fragColors[5] = texture2D(sampler5, vTextureCoord);", 
    " fragColors[6] = texture2D(sampler6, vTextureCoord);", 
    " fragColors[7] = texture2D(sampler7, vTextureCoord);", 
    "", 
    " lowp float fragIncluded[8];", 
    "", 
    " fragIncluded[0] = float(vTextureIndex <= 0.5);", 
    " fragIncluded[1] = float(vTextureIndex >= 0.5 && vTextureIndex < 1.5);", 
    " fragIncluded[2] = float(vTextureIndex >= 1.5 && vTextureIndex < 2.5);", 
    " fragIncluded[3] = float(vTextureIndex >= 2.5 && vTextureIndex < 3.5);", 
    " fragIncluded[4] = float(vTextureIndex >= 3.5 && vTextureIndex < 4.5);", 
    " fragIncluded[5] = float(vTextureIndex >= 4.5 && vTextureIndex < 5.5);", 
    " fragIncluded[6] = float(vTextureIndex >= 5.5 && vTextureIndex < 6.5);", 
    " fragIncluded[7] = float(vTextureIndex >= 6.5 && vTextureIndex < 7.5);", 
    "", 
    " lowp vec4 fragColor = fragColors[0] * fragIncluded[0] + ", 
    "       fragColors[1] * fragIncluded[1] + ", 
    "       fragColors[2] * fragIncluded[2] + ", 
    "       fragColors[3] * fragIncluded[3] + ", 
    "       fragColors[4] * fragIncluded[4] + ", 
    "       fragColors[5] * fragIncluded[5] + ", 
    "       fragColors[6] * fragIncluded[6] + ", 
    "       fragColors[7] * fragIncluded[7];", 
    "", 
    " gl_FragColor = fragColor * vTintColor;", 
    "}" 

一切正常,在大多數情況下細。但是在某些OSX機器上,有時採樣的紋理看起來不正確。具體來說,這似乎最常發生在基於NVidia的MacBook上,但我也可以在英特爾HD 5000上重現它。這發生在所有的Chrome,Safari和Firefox上,所以我很確定它與WebGL無關實施本身。這可能是OSX中的驅動程序錯誤嗎?我的場景是由一堆的UI組成的。大多數UI元素都是從一個UI精靈表中繪製的,並且文本是從位圖字體精靈表中繪製的。該錯誤通常表現爲使用UI精靈圖紋理繪製文本。我已經通過着色器修改進行了驗證,並且通過使用WebGL檢查器,我可以在繪製調用時將正確的紋理綁定到正確的採樣器。

我注意到這似乎是通過在一次繪製調用中將紋理A綁定到採樣器1並將紋理B綁定到採樣器2以及將它們顛倒的下一個繪製調用觸發的,其中紋理A綁定到採樣器2和紋理B綁定到sampler1。

這個問題目前可以在這個網址實況轉載:https://tinytappers.bigvikinggames.com/

這是最容易看到通過打開兩個底部菜單中的一個,雖然它的開放,輕按屏幕頂部的敵人。通常,攻絲本身或敵方死亡動畫足以使下方菜單中的文本在紋理之間快速切換。再次,這只是在幾個特定的​​OSX機器上。

其他人可以重現嗎?有誰知道發生了什麼?我很確定我傳遞給WebGL的數據是正確的。任何人都可以找到有關數據的任何問題?

+0

我無法在我的2014年15「mbp上進行回購,您應該嘗試製作一個較小的樣本,在您的遊戲中保留最少的示例,然後發佈該代碼 – gman

回答

0

我想我能夠解決這個問題。

我的代碼試圖很聰明,並跟蹤哪個紋理綁定到哪個紋理單元,然後只在需要更改時重新綁定它們。如果我在每次繪製調用之前總是明確地將紋理綁定到相應的紋理單元,問題就會消失。

在我做了這個解決方法之前,我甚至在某些情況下能夠崩潰WebGL(在所有3個瀏覽器中)。在這種情況下,崩潰發生在Apple Intel 5000驅動程序中(NVidia機器沒有崩潰)。

我仍然堅信這是某種驅動程序錯誤。我認爲紋理綁定在Apple OpenGL實現內部的繪製調用之間以某種方式被破壞。除非假定綁定的紋理將保持綁定是不安全的?

無論如何,我的解決方法現在工作,所以我只會去那。

+0

如果您可以製作一個小樣本,再現瀏覽器供應商將確保修復的bug – gman