致读者:“ gman的解决方案适用于该问题,但是我自己的问题在《守则》的不同部分中。”
我只想将我的场景渲染到具有DepthComponent_texuture的帧缓冲区。并希望将此纹理渲染到屏幕上,以便我可以在屏幕上看到DepthComponent。我想进入Shadowmapping,这是一个很好的练习。
我所做的事情:-set read/drawBuffer(s)
到gl.NONE
,因为我没有colorAttachment(甚至可能不重要)。-创建深度纹理时,我尝试了gl.texImage2D
,但无法使其正常工作。-当我使用由DepthAttachment
填充的ColorAttachment时,我得到了正常结果(颜色Attachment_texture只是具有可见性)[显然,在这里我还添加了DepthRenderbuffer(DEPTH24STENCTIL8)
]。
//creating the Framebuffer
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,width,height);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_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.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, atex, 0);
gl.drawBuffers([gl.NONE]);
gl.readBuffer(gl.NONE);
gl.bindFramebuffer(gl.FRAMEBUFFER,null);
//----------------
//In the renderLoop
//renders the scene with the pbrShader to the Framebuffer
//The FragmentShader of the PBRShader is empty cause i dont have any
//ColorAttachments and the Vertex is just transforming the position and
//passing the uvs[...]
render(scene,pbrShader,framebuffer);
//renders a texture to the screen using a very simple vertex shader and
//a Fragment Shader that just takes the texture and mapps it to the Screen
renderScreen(framebuffer.atex);
//Some more Code for clarity:
renderScene(scene,shader,fbo=null){
if(fbo!=null){
fbo.activate();
}
this.gl.fClear();
let batches = new Map();
let modals = scene.getEntitiesByType("modal");
modals.forEach(modal=>{
if(batches.has(modal.mesh)){
batches.get(modal.mesh).push(modal);
}else{
batches.set(modal.mesh,[modal]);
}
})
shader.activate().prepareScene(scene);
batches.forEach((batch,mesh)=>{
shader.prepareVAO(mesh);
batch.forEach(modal=>{
shader.prepareInstance(modal);
shader.drawVAO(mesh);
});
shader.unbindVAO(mesh);
});
shader.deactivate();
if(fbo!=null){
fbo.deactivate();
}
}
这里是在WebGL2中使用深度纹理的工作示例
const vs = `#version 300 es
layout(location = 0) in vec4 a_position;
out vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_position.xy * 0.5 + 0.5;
}
`;
const fs = `#version 300 es
precision mediump float;
in vec2 v_texcoord;
uniform sampler2D u_sampler;
out vec4 outColor;
void main() {
vec4 color = texture(u_sampler, v_texcoord);
outColor = vec4(color.r, 0, 0, 1);
}
`;
function main() {
var gl = document.querySelector("canvas").getContext('webgl2');
if (!gl) {
return alert("no WebGL2");
}
var program = twgl.createProgram(gl, [vs, fs]);
gl.useProgram(program);
var verts = [
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_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
// create a depth texture.
var depthTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, depthTex);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
const mipLevel = 0;
const depthTexWidth = 16;
const depthTexHeight = 16;
gl.texImage2D(
gl.TEXTURE_2D, mipLevel, gl.DEPTH_COMPONENT24,
depthTexWidth, depthTexHeight, 0,
gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
// Create a framebuffer and attach the textures.
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
gl.TEXTURE_2D, depthTex, 0);
// use some other texture to render with while we render to the depth texture.
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(
gl.TEXTURE_2D, 0, gl.RGBA8,
1, // width
1, // height
0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
// Turn on depth testing so we can write to the depth texture.
gl.enable(gl.DEPTH_TEST);
// note: we don't need to set u_sampler because uniforms
// default to 0 so it will use texture unit 0 which
// is the also the default active texture unit
// Render to the depth texture
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.viewport(0, 0, depthTexWidth, depthTexHeight);
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
// Now draw with the texture to the canvas
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.bindTexture(gl.TEXTURE_2D, depthTex);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>