Javascript WEBGL-FBO:为什么渲染调用后深度分量纹理为空

Javascript WEBGL-FBO:为什么渲染调用后深度分量纹理为空,javascript,framebuffer,webgl2,Javascript,Framebuffer,Webgl2,致读者: “gman的解决方案可以解决这个问题,但我自己的问题是代码的不同部分” 我只是想将我的场景渲染到一个具有深度分量的帧缓冲区。想把这个纹理渲染到屏幕上,这样我就可以在屏幕上看到DepthComponent了。我想学习阴影贴图,这将是一个很好的练习 我所做的事情: -将read/drawBuffer设置为gl.NONE,因为我没有颜色附件(甚至可能没有颜色)。 -创建深度纹理时,我尝试了gl.texImage2D,但无法使其工作。 -当我使用一个包含DepthAttachment的颜色附件

致读者: “gman的解决方案可以解决这个问题,但我自己的问题是代码的不同部分”

我只是想将我的场景渲染到一个具有深度分量的帧缓冲区。想把这个纹理渲染到屏幕上,这样我就可以在屏幕上看到DepthComponent了。我想学习阴影贴图,这将是一个很好的练习

我所做的事情:
-将read/drawBuffer设置为
gl.NONE
,因为我没有颜色附件(甚至可能没有颜色)。 -创建深度纹理时,我尝试了
gl.texImage2D
,但无法使其工作。 -当我使用一个包含
DepthAttachment
的颜色附件时,我得到了一个正常的结果(颜色附件的纹理只有sceen)[显然这里我还添加了一个
DepthRenderbuffer(depth24stentil8)
]

//创建帧缓冲区
id=gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,id);
atex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,atex);
gl.texStorage2D(gl.TEXTURE_2D,1,gl.DEPTH_COMPONENT16,宽度,高度);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MAG\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D、gl.TEXTURE_WRAP_S、gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE\u 2D、gl.TEXTURE\u WRAP\u T、gl.CLAMP\u至边缘);
gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.DEPTH_附件,gl.TEXTURE_2D,atex,0);
总账提取缓冲区([总账无]);
总帐读取缓冲区(总帐无);
gl.bindFramebuffer(gl.FRAMEBUFFER,null);
//----------------
//在renderLoop中
//使用pbrShader将场景渲染到帧缓冲区
//PBRShader的FragmentShader是空的,因为我没有
//颜色和顶点只是变换位置和位置
//通过UV[…]
渲染(场景、PBR着色器、帧缓冲区);
//使用非常简单的顶点着色器和
//一个片段着色器,它只获取纹理并将其映射到屏幕
渲染屏幕(framebuffer.atex);
//为了清晰起见,还有一些代码:
renderScene(场景、着色器、fbo=null){
如果(fbo!=null){
fbo.activate();
}
this.gl.fClear();
让batches=newmap();
让modals=scene.getEntitiesByType(“modal”);
modals.forEach(modal=>{
if(批处理has(模式网格)){
batches.get(modal.mesh)、push(modal);
}否则{
batches.set(modal.mesh,[modal]);
}
})
shader.activate().prepareScene(场景);
批次.forEach((批次,网格)=>{
着色器.prepareVAO(网格);
batch.forEach(模式=>{
着色器.prepareInstance(模态);
shader.drawVAO(网格);
});
着色器。取消绑定(网格);
});
shader.deactivate();
如果(fbo!=null){
fbo.deactivate();
}
}

下面是在WebGL2中使用深度纹理的工作示例

const vs=`#版本300 es
vec4 a_位置中的布局(位置=0);
out vec2 v_texcoord;
void main(){
gl_位置=a_位置;
v_texcoord=a_位置.xy*0.5+0.5;
}
`;
常数fs=`#版本300 es
精密中泵浮子;
在vec2 v_texcoord;
均匀取样器2D u_取样器;
外显vec4外显色;
void main(){
vec4颜色=纹理(u_采样器,v_texcoord);
outColor=vec4(color.r,0,0,1);
}
`;
函数main(){
var gl=document.querySelector(“canvas”).getContext(“webgl2”);
如果(!gl){
返回警报(“无WebGL2”);
}
var program=twgl.createProgram(gl[vs,fs]);
gl.useProgram(程序);
变量垂直=[
1,  1,  1, 
-1,  1,  0, 
-1, -1, -1,
1,  1,  1, 
-1, -1, -1,
1, -1,  0,
];
var vertBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,vertBuffer);
gl.bufferData(gl.ARRAY\u BUFFER、新Float32Array(verts)、gl.STATIC\u DRAW);
gl.EnableVertexAttributeArray(0);
gl.VertexAttribute指针(0,3,gl.FLOAT,false,0,0);
//创建深度纹理。
var depthTex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,深度特克斯);
gl.texParameteri(gl.TEXTURE_2D、gl.TEXTURE_WRAP_S、gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE\u 2D、gl.TEXTURE\u WRAP\u T、gl.CLAMP\u至边缘);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MAG\u过滤器,gl.NEAREST);
常数mip=0;
常数depthTexWidth=16;
常数depthTexHeight=16;
gl.texImage2D(
gl.TEXTURE_2D、mipLevel、gl.DEPTH_组件24、,
depthTexWidth,depthTexHeight,0,
gl.DEPTH\u COMPONENT,gl.UNSIGNED\u INT,null);
//创建帧缓冲区并附加纹理。
var fb=gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.DEPTH_附件,
gl.TEXTURE_2D,深度为0);
//在渲染到深度纹理时,使用其他纹理进行渲染。
常量tex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texImage2D(
gl.TEXTURE_2D,0,gl.RGBA8,
1,//宽度
1,//高度
0,gl.RGBA,gl.UNSIGNED_字节,新的Uint8Array([0,0,255,255]);
//启用深度测试,以便写入深度纹理。
总帐启用(总帐深度测试);
//注意:我们不需要设置u_采样器,因为
//默认值为0,因此它将使用纹理单元0
//也是默认的活动纹理单位
//渲染到深度纹理
gl.bindFramebuffer(gl.FRAMEBUFFER,fb);
总图视口(0,0,depthTexWidth,depthTexHeight);
总账清除(总账深度\缓冲\位);
gl.绘图阵列(gl.三角形,0,6);
//现在将纹理绘制到画布上
gl.bindFramebuffer(gl.FRAMEBUFFER,null);
总图视口(0,0,总图画布宽度,总图画布高度);
gl.bindTexture(gl.TEXTURE_2D,深度特克斯);
gl.绘图阵列(gl.三角形,0,6);
}
main()

下面是在WebGL2中使用深度纹理的工作示例

const vs=`#版本300 es
vec4 a_位置中的布局(位置=0);
out vec2 v_texcoord;
void main(){
gl_位置=a_位置;