【问题标题】:OpenGL/WebGL - Incorrect depth when rendering to texture/framebuffer twice?OpenGL/WebGL - 两次渲染到纹理/帧缓冲区时深度不正确?
【发布时间】:2017-12-28 20:56:56
【问题描述】:

我正在尝试使用 webgl 在简单模型上实现体积渲染。为此,我需要单独纹理中的背面,只需将简单的传递渲染到这样的纹理:

var tx = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tx);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.FLOAT, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
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);
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tx, 0);
//setup viewport
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0.9, 0.9, 0.9, 1.0);
//setup culling and depth testing
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LESS);
//render elements
if (model.index) {
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.drawElements(gl.TRIANGLES, numItems, gl.UNSIGNED_SHORT, 0);
}
else {
    gl.drawArrays(gl.TRIANGLES, numItems, 0);
}

这和预期的一样,片段着色器只是一个:

gl_FragColor = vec4((0.5 * v_pos) + 1.0, 1.0);

但是,当我尝试将此纹理从帧缓冲区传递到一个新的着色器时,我想像这样执行实际的 raymarching/volumerendering:

//2nd renderpass to canvas
//switch program
//set current shader
context.shader = volPrgr;
//activate the shader
context.gl.useProgram(volPrgr);
var gl = context.gl;
var shader = context.shader;
if (!shader) {
    return;
}
init(gl);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//setup viewport
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);

//init buffers
.
.
.

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, tx);
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var textureLoc = gl.getUniformLocation(context.shader, 'u_back');
if (isValidUniformLocation(textureLoc) ){
    gl.uniform1i(textureLoc, 0);
}else{
    console.log(textureLoc + " is not a valid texturelocation.");
}
//send screensize needed for texture lookup
gl.uniform1i(gl.getUniformLocation(context.shader, 'u_screenRexX'), gl.drawingBufferWidth);
gl.uniform1i(gl.getUniformLocation(context.shader, 'u_screenRexY'), gl.drawingBufferHeight);
gl.disable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LESS);
//setup viewport
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0.9, 0.9, 0.9, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//render elements
if (model.index) {
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.drawElements(gl.TRIANGLES, numItems, gl.UNSIGNED_SHORT, 0);
}
else {
    gl.drawArrays(gl.TRIANGLES, numItems, 0);
}

在着色器中:

vec2 lookup = (vec2(gl_FragCoord.x/float(u_screenRexX), gl_FragCoord.y/float(u_screenRexY)));
vec3 back = vec3(texture2D(u_back, lookup)).rgb;
gl_FragColor = vec4(back.rgb, 1.0);

我只是尝试使用屏幕空间坐标将纹理渲染到模型上时得到这个:

这怎么可能?我可以更改体积着色器的深度顺序以正确显示模型/纹理(机翼前面的鸟头)吗?谢谢

【问题讨论】:

    标签: webgl


    【解决方案1】:

    我忘了在我的帧缓冲区中添加深度纹理,这成功了:

      gl.getExtension( "WEBKIT_WEBGL_depth_texture" );
      gl.getExtension( "MOZ_WEBGL_depth_texture" );
      
      .
      .
      .
      
      var depth = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, depth);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
        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.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depth, 0);
     
        //setup viewport
        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
        gl.clearColor(0.9, 0.9, 0.9, 1.0);
        gl.clearDepth(1.0);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.depthMask(true);
        gl.enable(gl.CULL_FACE);
        gl.cullFace(gl.FRONT);
        gl.enable(gl.DEPTH_TEST);
        gl.depthFunc(gl.LESS);
        
        //render
     

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      相关资源
      最近更新 更多