【发布时间】:2018-01-16 19:03:23
【问题描述】:
试图了解与通用移动目标的 WebGL 开发相关的许多问题,现在我需要将深度信息存储在纹理附件中以供以后检索和后期处理。
JavaScript:
var depthRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
顶点着色器:
precision mediump float;
uniform mat4 u_transformMatrix;
attribute vec3 a_position;
varying float v_depth;
void main() {
vec4 tcoords = u_transformMatrix * vec4(a_position, 1.0);
v_depth = 0.5 * (tcoords.z + 1.0);
gl_Position = tcoords;,
}
片段着色器:
precision mediump float;
varying float v_depth;
vec4 PackDepth(in float frag_depth) {
vec4 bitSh = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
vec4 bitMsk = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 enc = fract(frag_depth * bitSh);
enc -= enc.xxyz * bitMsk;
return enc;
}
float UnpackDepth( const in vec4 enc ) {
const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
float decoded = dot( enc, bit_shift );
return decoded;
}
void main() {
vec4 encoded_depth;
float decoded_depth;
encoded_depth = PackDepth(v_depth);
decoded_depth = UnpackDepth(encoded_depth);
//gl_FragColor = vec4(vec3(decoded_depth), 1.0);
gl_FragColor = encoded_depth;',
}
这是我现在得到的:左:iPad PRO/Android/desktop Chrome --emulate-shader-precision,中:桌面 FF/Chrome(无标志),右:编码和解码(显然是 256 色调灰色-规模)
我尝试了许多不同的打包/拆包方法,但似乎都没有奏效。 关于我做错了什么有什么建议吗?
此外,我还注意到许多使用 RGBA 纹理来存储深度信息的最常见 WebGL 库的示例都被破坏了 - 我相信出于同样的原因,打包/解包函数的某个地方存在问题。
编辑:Three.js 中的相同问题:https://github.com/mrdoob/three.js/issues/9092
有趣的是,如果我使用旧的 mod 方法来包装深度,我 获得更高的精度(至少更多位)
使用mediump 精度存储和检索深度信息的正确方法是什么?
【问题讨论】:
-
@Rabbid76:我在 Google 上搜索了一个 SSAO 演示,该演示适用于我的测试设备(iPhone 5/6、iPad PRO、Android),但我找不到任何东西。用 Three.js 问题编辑了我的问题,iOS 设备也有同样的问题。在 Android 中它的工作方式略有不同,还不知道具体原因,可能是 iOS 错误。
标签: javascript glsl webgl shader depth-buffer