我正在尝试使用 samplerCubeShadow 使 OpenGL 阴影映射代码适应 WebGL,并且我拼命系统地陷入死胡同,因为第一个和第二个之间的有效数据格式和存储显然不一样。
我知道我可以使用其他采样器而不是sampler*Shadow
通过以其他方式渲染到纹理来实现阴影映射,但是,如果可能的话,我希望实现与我在 OpenGL 中相同的方式。
我的问题是找到(如果存在的话!)格式、内部格式以及 WebGL/GLSL 对 samplerCubeShadow 采样器的期望的良好组合......
1.问题:目标深度纹理格式。
在 OpenGL 中,我使用以下格式作为深度纹理:
GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT
但似乎 WebGL 唯一被接受的组合DEPTH_ATTACHEMENT
是
gl.DEPTH_COMPONENT16, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT
我试过了gl.FLOAT
,gl.HALF_FLOAT
但texImage2D
拒绝了另一种类型gl.UNSIGNED_SHORT
。
它是 WebGL 中深度纹理的好格式吗?如果是,那么 WebGL 将深度数据存储在 16 位整数而不是浮点数中,这听起来很奇怪,但不是真正的问题,因为 16 位就是 16 位。它真的是 WebGL 中唯一可接受的深度纹理格式吗?
2.问题:纹理不可渲染
我可以毫无错误地绘制此纹理,但是,当将纹理绑定到我samplerCubeShadow
的 .
texture bound to texture unit # is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
从此
要么我找到了一种“可渲染”的格式,但它不能用作DEPTH_ATTACHEMENT
,或者我找到了一个合适的格式DEPTH_ATTACHEMENT
,它不是“可渲染”的......那么,解决方案是什么?
伪代码:
gl.bindTexture(gl.TEXTURE_CUBE_MAP, shadow_cube);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, 0x2800, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, 0x2800, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_R_TO_TEXTURE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, gl.GREATER);
for(var c = 0; c < 6; c++) {
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X+c, 0, gl.DEPTH_COMPONENT16, 512, 512, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
}
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, offscreen_fbo);
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
for(var c = 0; c < 6; c++) {
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X+c, shadow_cube, 0);
// draw things...
}
gl.activeTexture(gl.TEXTURE#);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, shadow_cube);
编辑:在 OpenGL 代码中,目标深度纹理有一个额外的参数:
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
但是,DEPTH_TEXTURE_MODE
WebGL 中不存在 ......也许这是在 WebGL 中工作所缺少的?