WebGL 着色器保存多个 32 位值
WebGL shader save multiple 32 bit values
我需要在每个 WebGL 片段着色器调用中保存最多 8 个 32 位值(包括没有 OES_texture_float 或 OES_texture_half_float 扩展可用的情况)。看来我只能通过将其打包成 4x8 位 RGBA gl_FragColor 来存储单个 32 位值。
有没有办法存储 8 个值?
在片段着色器中每次调用绘制多于一个 vec4 数据的唯一方法是使用 WEBGL_draw_buffers
,它允许您将多个颜色附件绑定到一个帧缓冲区,然后在一个帧缓冲区中渲染所有这些附件使用
的单个片段着色器调用
gl_FragData[constAttachmentIndex] = result;
如果 WEBGL_draw_buffers
不可用,我能想到的唯一解决方法是
在多个绘图调用中渲染。
调用 gl.drawArrays
渲染第一个 vec4
,然后再次使用不同的参数或不同的着色器渲染第二个 vec4
。
渲染基于 gl_FragCoord,您可以在其中更改每个像素的输出。
换句话说,第一个像素得到第一个vec4,第二个像素得到第二个vec4,等等。例如
float mode = mod(gl_Fragcoord.x, 2.);
gl_FragColor = mix(result1, result2, mode);
这样存储的结果是这样的
1212121212
1212121212
1212121212
合并为一个纹理。要获得更多 vec4,您可以这样做
float mode = mod(gl_Fragcoord.x, 4.); // 4 vec4s
if (mode < 0.5) {
gl_FragColor = result1;
} else if (mode < 1.5) {
gl_FragColor = result2;
} else if (mode < 2.5) {
gl_FragColor = result3;
} else {
gl_FragColor = result4;
}
这可能比方法 #1 快,也可能不快。您的着色器更复杂,因为它可能会为每个像素同时计算 result1 和 result2,但根据 GPU 和流水线,您可能会免费获得其中的一些。
至于即使没有 OES_texture_float
也能输出 32 位值,您基本上必须使用上述 3 种技术之一写出更多 8 位值。
在 WebGL2 中,绘制缓冲区是一项必需的功能,而在 WebGL1 中它是可选的。在 WebGL2 中,还有将顶点着色器(变量)的输出写入缓冲区的变换反馈。
我需要在每个 WebGL 片段着色器调用中保存最多 8 个 32 位值(包括没有 OES_texture_float 或 OES_texture_half_float 扩展可用的情况)。看来我只能通过将其打包成 4x8 位 RGBA gl_FragColor 来存储单个 32 位值。 有没有办法存储 8 个值?
在片段着色器中每次调用绘制多于一个 vec4 数据的唯一方法是使用 WEBGL_draw_buffers
,它允许您将多个颜色附件绑定到一个帧缓冲区,然后在一个帧缓冲区中渲染所有这些附件使用
gl_FragData[constAttachmentIndex] = result;
如果 WEBGL_draw_buffers
不可用,我能想到的唯一解决方法是
在多个绘图调用中渲染。
调用
gl.drawArrays
渲染第一个vec4
,然后再次使用不同的参数或不同的着色器渲染第二个vec4
。渲染基于 gl_FragCoord,您可以在其中更改每个像素的输出。
换句话说,第一个像素得到第一个vec4,第二个像素得到第二个vec4,等等。例如
float mode = mod(gl_Fragcoord.x, 2.); gl_FragColor = mix(result1, result2, mode);
这样存储的结果是这样的
1212121212 1212121212 1212121212
合并为一个纹理。要获得更多 vec4,您可以这样做
float mode = mod(gl_Fragcoord.x, 4.); // 4 vec4s if (mode < 0.5) { gl_FragColor = result1; } else if (mode < 1.5) { gl_FragColor = result2; } else if (mode < 2.5) { gl_FragColor = result3; } else { gl_FragColor = result4; }
这可能比方法 #1 快,也可能不快。您的着色器更复杂,因为它可能会为每个像素同时计算 result1 和 result2,但根据 GPU 和流水线,您可能会免费获得其中的一些。
至于即使没有 OES_texture_float
也能输出 32 位值,您基本上必须使用上述 3 种技术之一写出更多 8 位值。
在 WebGL2 中,绘制缓冲区是一项必需的功能,而在 WebGL1 中它是可选的。在 WebGL2 中,还有将顶点着色器(变量)的输出写入缓冲区的变换反馈。