Javascript Webgl-添加深度模板renderbuffer可防止渲染到cubemap帧缓冲区

Javascript Webgl-添加深度模板renderbuffer可防止渲染到cubemap帧缓冲区,javascript,opengl-es,webgl,opengl-es-2.0,Javascript,Opengl Es,Webgl,Opengl Es 2.0,我们正在Webgl 1中工作,并尝试使用模具渲染到立方体贴图。单独渲染立方体贴图效果很好。当我们添加一个DEPTH_模具renderbuffer时,它会停止写入立方体映射,并且不会发出任何错误 这不会发生在普通的纹理\u 2D而不是纹理\u立方体\u贴图的情况下 深度/模板/剪切测试已禁用 调用framebufferRenderbuffer会破坏它 将renderbuffer切换为仅为模具或仅为深度具有相同的效果 将renderbuffer切换为颜色缓冲区可使其再次工作 这是一个小小的消遣。

我们正在Webgl 1中工作,并尝试使用模具渲染到立方体贴图。单独渲染立方体贴图效果很好。当我们添加一个
DEPTH_模具
renderbuffer时,它会停止写入立方体映射,并且不会发出任何错误

  • 这不会发生在普通的
    纹理\u 2D
    而不是
    纹理\u立方体\u贴图的情况下
  • 深度/模板/剪切测试已禁用
  • 调用
    framebufferRenderbuffer
    会破坏它
  • 将renderbuffer切换为仅为模具或仅为深度具有相同的效果
  • 将renderbuffer切换为颜色缓冲区可使其再次工作
这是一个小小的消遣。正如您所看到的,我们得到了一个控制台输出,前三个调用的值正确,最后一个调用的值为零

为什么会发生这种情况?我们缺少什么小东西来让renderbuffers与cubemaps一起工作

const canvas=document.createElement(“canvas”);
const gl=canvas.getContext(“webgl”);
日志(测试(假,假));
日志(测试(假、真));
日志(测试(真、假));
日志(TEST(true,true));
功能测试(useCubemap、useBuffer){
常数大小=512;
const textureType=useCubemap?gl.TEXTURE\u CUBE\u MAP:gl.TEXTURE\u 2D;
//设置程序
{
const program=gl.createProgram();
const vertShader=gl.createShader(gl.VERTEX\u着色器);
常量fragShader=gl.createShader(gl.FRAGMENT\u着色器);
gl.shaderSource(顶点着色器`
属性向量2 a_位置;
void main(){
gl_位置=vec4(a_位置,0.2,1.0);
}
`);
总帐编译头(vertShader);
gl.attachShader(程序、顶点着色器);
gl.着色器源(fragShader`
void main(){
gl_FragColor=vec4(0.1,0.2,0.3,0.4);
}
`);
总帐编译主管(fragShader);
德国劳埃德大学附属学院(fragShader项目);
总账链接程序(程序);
gl.useProgram(程序);
}
//设置四边形
{
const posBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,posBuffer);
gl.EnableVertexAttributeArray(0);
gl.VertexAttribute指针(0,2,gl.FLOAT,false,0,0);
总账缓冲数据(总账数组缓冲区,新Float32Array([-1,+1,-1,+1,+1,+1,-1]),总账静态绘图);
}
//设置帧缓冲区
{
const fb=gl.createFramebuffer();
const targetTexture=gl.createTexture();
gl.bindFramebuffer(gl.FRAMEBUFFER,fb);
gl.bindTexture(textureType、targetTexture);
gl.texParameteri(textureType,gl.TEXTURE\u MIN\u FILTER,gl.NEAREST);
gl.texParameteri(textureType,gl.TEXTURE\u MAG\u FILTER,gl.NEAREST);
gl.texParameteri(textureType、gl.TEXTURE\u WRAP\u S、gl.CLAMP\u TO\u EDGE);
gl.texParameteri(textureType,gl.TEXTURE\u WRAP\u T,gl.CLAMP\u至边);
//切换纹理类型
如果(textureType==gl.TEXTURE\U 2D){
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,大小,大小,0,gl.RGBA,gl.UNSIGNED_字节,null);
gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,targetTexture,0);
}否则{
对于(设i=0;i<6;i++)gl.texImage2D(gl.TEXTURE\u CUBE\u MAP\u POSITIVE\u X+i,0,gl.RGBA,大小,0,gl.RGBA,gl.UNSIGNED\u BYTE,null);
gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_CUBE_MAP_POSITIVE_X,targetTexture,0);
}
}
//设置渲染缓冲区
{
常量rb=gl.createRenderbuffer();
gl.BinderBuffer(gl.RENDERBUFFER,rb);
gl.RENDERBUFFER存储(gl.RENDERBUFFER,gl.DEPTH_模具,尺寸,尺寸);
//把这个拿出来就行了
如果(使用缓冲区)gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_模具_附件,gl.RENDERBUFFER,rb);
}
//使明显的罪犯失去能力
gl.禁用(gl.深度测试);
总帐禁用(总帐模板测试);
gl.禁用(gl.剪刀试验);
//做一个约会操
总图视口(0,0,大小,大小);
总图.绘图阵列(总图.三角带,0,4);
//抓住机会
常数像素=新的UINT8阵列(4);
gl.readPixels(0,0,1,1,gl.RGBA,gl.UNSIGNED_字节,像素);
返回像素;

}
这对我很有用。在您发布的代码中,我得到的所有4个调用的值都相同。您使用的是什么操作系统/GPU/驱动程序?如果你使用Chrome,你能粘贴你的
about:gpu
内容吗

这听起来像是你的驱动程序中的一个bug。这可能也是WebGL规范中的一个bug

OpenGL ES规范不需要帧缓冲区附件的任何组合(零、零、零、nada)。WebGL规范需要3种组合才能工作。发件人:

当所有附件都是帧缓冲区附件完整、非零且具有相同的宽度和高度时,帧缓冲区对象附件的以下组合必须导致帧缓冲区完整:

  • 颜色\u附件0=RGBA/无符号\u字节纹理
  • 颜色\附件0=RGBA/无符号\字节纹理+深度\附件=深度\组件16渲染缓冲
  • 颜色\附件0=RGBA/无符号\字节纹理+深度\模具\附件=深度\模具渲染缓冲
但是看看WebGL一致性测试

因此,首先,这表明您的驱动程序/gpu不支持与cubemaps的组合。通过调用
gl.checkFramebufferStatus
进行测试。如果未返回
gl.FRAMEBUFFER\u COMPLETE
则安装程序不支持渲染到带有深度模具附件的立方体贴图

const canvas=document.createElement(“canvas”);
const gl=canvas.getContext(“webgl”);
测试(“纹理2D”、“深度分量16”);
测试(“纹理2D”、“深度模板”);
测试(“纹理立方体贴图”、“深度分量16”);
测试(“纹理立方体贴图”、“深度模板”);
功能测试(目标、深度缓冲区格式){
常数大小=16;
const textureType=gl[target];
//设置帧缓冲区
{
常数fb=gl.createFra