假设我正在渲染 2 个样本,这些样本将组合成单个图像。第一个样本包含可显示像素范围之外的值(在本例中大于 1)。但当减去第二个样本时,它确实落在该范围内。
在组合样本之前,我将样本存储在帧缓冲区纹理中。
我希望能够存储大于 1 的值,但这些值被限制为 1。GLSL 片段着色器可以输出这样的值吗?纹理可以存储它们吗?如果没有,我还能如何存储它们?
根据此页面,有可能:
渲染到屏幕要求输出具有可显示的格式,这在多通道管道中并不总是如此。有时,通道生成的纹理需要具有浮点格式,该格式不会直接转换为颜色
但根据规范,纹理浮点数被限制在 [0,1] 范围内。
最简单的方法是使用浮点纹理。
var gl = someCanvasElement.getContext("experimental-webgl");
var ext = gl.getExtension("OES_texture_float");
if (!ext) {
alert("no OES_texture_float");
return;
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用浮点纹理创建和渲染。接下来要做的就是看看是否可以渲染到浮点纹理。
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null);
gl.texParameteri(gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_MAG_FILTER, gl.NEAREST);
var fb = gl.createFramebuffer();
gl.bindFrameBuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
alert("can not render to floating point textures");
return;
}
Run Code Online (Sandbox Code Playgroud)
使用时浮球未夹紧OES_texture_float
如果设备不支持渲染为浮点纹理,那么您必须像 gil 建议的那样以其他方式对结果进行编码
注意:在 WebGL2 中,浮点纹理始终可用。另一方面,OES_texture_float_linear如果您想过滤浮点纹理,您仍然需要检查并启用。此外,在 WebGL2 中,您需要启用EXT_color_buffer_float渲染为浮点纹理(并且您仍然需要调用,gl.checkFramebufferStatus因为这取决于驱动程序支持哪些附件组合)。此外,还有 EXT_float_blend渲染到浮点纹理时是否可以启用混合的问题。