【问题标题】:Is there a way to cache slow WebGL shader compilation if the shader never changes?如果着色器从不改变,有没有办法缓存慢速 WebGL 着色器编译?
【发布时间】:2012-05-24 11:36:44
【问题描述】:

我有一个 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.)

【问题讨论】:

    标签: shader webgl


    【解决方案1】:

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

    antialias_level 是用户选择的参数,在整个场景中都是不变的吗?为当前选择的关卡而不是所有可能的关卡编译着色器可能会更好;这可能在运行时效率更高,编译速度也更快。

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

    【讨论】:

    • 非常中肯的建议,但要强调一点:目前没有办法预编译 WebGL 着色器。如果我们确实获得了这种能力,那可能是一条出路。
    【解决方案2】:

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

    另一方面,两种浏览器很可能会在未来开始为您缓存着色器

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多