我有一个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有关。
答案 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或其他浏览器是否有类似的版本。