2012-05-23 60 views
1

我有一個WebGL的着色器,其立即編譯感知(在Windows 7上的Chrome)時,我有這樣的:如果着色器永不改變,有沒有辦法緩存緩慢的WebGL着色器編譯?

void main(void) { 
    if (antialias_level == 1) 
     gl_FragColor = NewtonIteration((gl_FragCoord.xy + offset)/zoom); 
    else if (antialias_level == 2) 
     gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, -0.25))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, 0.25))/zoom)) * 0.5; 
} 

但它需要一個很長的時間(約10秒)編譯此:

void main(void) { 
    if (antialias_level == 1) 
     gl_FragColor = NewtonIteration((gl_FragCoord.xy + offset)/zoom); 
    else if (antialias_level == 2) 
     gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, -0.25))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, 0.25))/zoom)) * 0.5; 
    else if (antialias_level == 4) 
     gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, -0.25))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.25, 0.25))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, -0.25))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.25, 0.25))/zoom)) * 0.25; 
    else if (antialias_level == 9)\ 
     gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.33, -0.33))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.0, -0.33))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.33, -0.33))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.33, 0.0))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.0, 0.0))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.33, 0.0))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.33, 0.33))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.0, 0.33))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.33, 0.33))/zoom)) * 0.111111111; 
    else if (antialias_level == 16)\ 
     gl_FragColor = (NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.375, -0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.125, -0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.125, -0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.375, -0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.375, -0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.125, -0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.125, -0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.375, -0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.375, 0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.125, 0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.125, 0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.375, 0.125))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.375, 0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(-0.125, 0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.125, 0.375))/zoom) + NewtonIteration((gl_FragCoord.xy + offset + vec2(0.375, 0.375))/zoom)) * 0.0625; 
} 

有沒有辦法將WebGL編譯的結果緩存到二進制文件並加載它,或者不會有幫助?我假設長時間的延遲與從OpenGL到DirectX的着色器轉換有關。

Here's a live example

回答

3

我不知道的任何方式進行預編譯的WebGL着色;提供這樣的功能可能會帶來許多便攜性和安全性問題。

antialias_level用戶選擇的參數對於整個場景是不變的嗎?您可能會更好地編譯當前選定級別的着色器,而不是所有可能的着色器;這可能會在運行時更高效並且編譯速度更快。

定製着色器,同時仍然將着色器源與JS代碼分離的一種簡單方法是在編譯前加上"#define ANTIALIAS_LEVEL " + level,並在着色器源代碼中使用#if來選擇適當的大小寫。但是,由於您的main()代碼非常系統化,因此可能需要通過算法生成代碼。

+1

非常合理的建議,但要強調一點:*目前*無法預編譯WebGL着色器。如果我們確實獲得了這種能力,它可能會成爲一種解決辦法。 – Toji

1

不,沒有辦法預先編譯着色器。這將是一個巨大的安全漏洞。

在另一方面,它可能是這兩個瀏覽器將開始高速緩存着色器在未來你引擎蓋

這裏下對鉻 http://code.google.com/p/chromium/issues/detail?id=88572

這個問題我不知道是否有類似的Firefox或其他瀏覽器。