2

I am trying to implement volume rendering on a simple model with webgl. For this to work I need the backfaces in a seperate texture, simply by rendering a simple pass to texture like this:

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);
}

this works like expected, the fragment shader simply is a:

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

enter image description here

However when I then try to pass this texture from the framebuffer into a new shader where i want to perform the actual raymarching/volumerendering like this:

//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);
}

and in the shader:

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);

I get this when simply trying to render the texture onto the model using screenspace coordinates:

enter image description here

How is this possible? Can I change the Depth ordering for the volume shader for it to dsiplay the model/texture correctly (head of the bird in front of the wing)? Thank you

0

1 Answer 1

1

I forgot to add a depth texture to my framebuffer, that did the trick:

  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
 

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.