如果着色器永远不会改变,有没有办法缓存慢速WebGL着色器编译?

时间:2012-05-23 14:05:31

标签: shader webgl

我有一个WebGL着色器,当我有这个时,会立即在感知上编译(Windows 7上的Chrome):

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。)

2 个答案:

答案 0 :(得分:3)

我不知道有任何预编译WebGL着色器的方法;提供这样的功能可能会有很多可移植性和安全性问题。

antialias_level用户选择的参数是否对整个场景都是常量?你可能最好为目前选择的级别而不是所有可能的级别编译着色器;这可能在运行时更有效,也可以更快地编译。

在将着色器源与JS代码分离的同时自定义着色器的一种简单方法是在编译之前添加"#define ANTIALIAS_LEVEL " + level,并在着色器源中使用#if选择适当的大小写。但是,由于您的main()代码非常系统化,因此可能需要通过算法生成它。

答案 1 :(得分:2)

不,没有办法预编译着色器。这将是一个巨大的安全漏洞。

另一方面,很可能两个浏览器都会在未来为您启动缓存着色器

以下是Chrome的问题 http://code.google.com/p/chromium/issues/detail?id=88572

我不确定Firefox或其他浏览器是否有类似的版本。