问题
Ok so I have a framebuffer with a bunch of attachments attached. The attachments are Color, Bloom, Velocity and Depth.
I start by clearing the framebuffer to the values of my choosing with the following code.
// Clear Color Buffer
float colorDefaultValue[4] = { 0.5, 0.5, 0.5, 1.0 };
glClearBufferfv(GL_COLOR, 0, colorDefaultValue);
// Clear Bloom Buffer
float bloomDefaultValue[4] = { 0.0, 0.0, 1.0, 1.0 };
glClearBufferfv(GL_COLOR, 1, bloomDefaultValue);
// Clear Depth Buffer
float depth[1] = { 1.0 };
glClearBufferfv(GL_DEPTH, 0, depth);
Then I proceed to render the scene using my main shader. As you can see in the code below, Ive specified the outputs.
// Layouts
layout (location = 0) out vec4 o_vFragColor;
layout (location = 1) out vec4 o_vBloomColor;
And then i output values in the fragment shader to them.
o_vFragColor = vec4(color, alpha);
float brightness = dot(o_vFragColor.rgb, vec3(0.2126, 0.2126, 0.2126));
if(brightness > 1.0)
o_vBloomColor = vec4(o_vFragColor.rgb, 1.0);
Now, my question is: If a fragment is not bright enough, why does it output black to the bloom attachment? I haven't specified for it to output anything yet it adjusts it anyway.
For example, if I clear the bloom buffer to green
// Clear Bloom Buffer
float bloomDefaultValue[4] = { 0.0, 1.0, 0.0, 1.0 };
glClearBufferfv(GL_COLOR, 1, bloomDefaultValue);
and I dont output any value to the bloom attachment in the fragment shader, I get a black in the bloom buffer. You can see it it the following image.
BloomBuffer
The parts of the image where the buffer is green is where no geometry was drawn. The black parts are parts of the image that contained geometry that was not bright enough and therefore should have not outputted anything to the bloom buffer, yet they clearly did output something, black in this case. Purple parts are fragments that are beyind the brightness threshold and working as intended.
What with the black?
回答1:
You cannot write to a color buffer conditionally from within a fragment shader.
An output fragment always has values for each active color buffer, even if you didn't write them. This is true even if you don't declare a variable for that output value. If no value gets written to a particular fragment output location, then the value used will be undefined. But it will be something.
You can do conditional writing based on color masking. But that is a per-draw-call thing, not something that can be done in the fragment shader. You could employ blending in that color buffer, using an alpha of 0 to mean "don't write", and an alpha of 1 to replace what's there.
来源:https://stackoverflow.com/questions/39545966/opengl-3-0-framebuffer-outputting-to-attachments-without-me-specifying