Okay, so i’m expanding on weighted average sums for order independent transparency.
My idea is so, to add a single “depth” pass to the shader pipeline with GL_MIN_EXT blend equation. To store the least depth coordinate of any opaque objects and discard fragments greater than this on the “init” pass of the weighted average shader.
For those confused, ignore everything I just said, essentially I’m just trying to emulate a depth pass. The problem is its really not working out, even if I add a tolerance value
init code
#ifdef MACOSX
FLOAT_R32 = GL_RGBA16F_ARB;
#endif
multipass_mode = MP_WEIGHTED_AVG;
glGenTextures(4, fbo_textures);
for(int i = 0; i < 4; i++)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo_textures[i]);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if(i == 0) //background
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if(i == 3) //min depth
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
else if(i == 1)
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
else if(i == 2)
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, FLOAT_R32, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
}
//add a pass that uses GL_MIN to blend equation, store in texture, now use it as the end all
//stopping point in the "init" pass. gooooood
//background fbo
fbos[0] = new FrameBuffer();
fbos[0]->attach_texture(fbo_textures[0], GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB);
//depth pass fbo
fbos[1] = new FrameBuffer();
fbos[1]->attach_texture(fbo_textures[3], GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB);
//weighted average shader target fbo
fbos[2] = new FrameBuffer();
fbos[2]->attach_texture(fbo_textures[1], GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB);
fbos[2]->attach_texture(fbo_textures[2], GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB);
draw code
for(int f = 0; f < 3; f++)
{
glLoadIdentity();
fbos[f]->bind();
//depth pass
if(f == 1)
{
glBlendEquationEXT(GL_MIN_EXT);
glEnable(GL_BLEND);
use_depth_rec_shader();
glClearColor(1, 1, 1, 1);
}
if(f == 2)
{
const GLenum drawbuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
glDrawBuffers(2, drawbuffers);
glBlendEquationEXT(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo_textures[3]);
//use_wavg_init_shader();
glClearColor(0, 0, 0, 0);
}
fbos[f]->clear(GL_COLOR_BUFFER_BIT);
draw_3d(false, i, fbos[f]);
fbos[f]->unbind();
glUseProgram(0);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
glDrawBuffer(GL_BACK);
}
depth shader
//vert
void main(void)
{
gl_FrontColor = gl_FrontMaterial.diffuse;
gl_Position = ftransform();
}
//frag
void main()
{
if(gl_Color.a >= 1.0)
gl_FragColor = vec4(0, 0, 0, gl_FragCoord.z+0.0005);
else
gl_FragColor = vec4(0, 0, 0, 1.0);
}
rendering fragment shader
uniform sampler2DRect DepthTex;
vec4 ShadeFragment();
void main()
{
//my little depth test
if(gl_FragCoord.z > texture2DRect(DepthTex, gl_FragCoord.xy).a)
{
//gl_FragData[0] = vec4(0.0);
//gl_FragData[1] = vec4(0.0);
discard;
}
else
{
vec4 color = ShadeFragment();
gl_FragData[0] = vec4(color.rgb * color.a, color.a);
gl_FragData[1] = vec4(1.0);
}
}
The ugly result: