PDA

View Full Version : transparency does not work



3DPrgmer
01-11-2017, 07:43 AM
i tried to add transparency to my ogl project. For now i just made it hardcoded in the fragmentshader. Later i'll get the value via pipeline. But first that will do. Or rather it does not do. It's still solid painted. Is there anything else i need to change?? All i did was changing this


gl_FragColor = texture2D(texture, v_texcoord);

to


vec4 finalColor = vec4(texture2D(texture, v_texcoord));
finalColor.a = 0.3;
gl_FragColor = finalColor;



#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif

uniform sampler2D texture;

varying vec2 v_texcoord;

void main()
{
// Set fragment color from texture
vec4 finalColor = vec4(texture2D(texture, v_texcoord));
finalColor.a = 0.3;
gl_FragColor = finalColor;
}

john_connor
01-11-2017, 10:26 AM
transparency does not happen by magic, you have to do it yourself
most common approach is this:

--> enable blending: glEnable(GL_BLEND);
that means the color drawn into the framebuffer by your fragmentshader will be "somehow" mixed with the color that is already written into the framebuffer at that position

most common approach is this:
--> discard the alpha value that is already written into the framebuffer
--> control "somehow" the transparency with the alpha value your fragmentshader writes into the framebuffer

"somehow" means setting the math operation to:
--> glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

that means these "weight factors":
k(src) = alpha
k(dest) = 1 - alpha

final framebuffer color = k(src) * color(src) + k(dest) * color(dest)
color(dest) = old framebuffer color
color(scr) and alpha = fragmentshader output

to achieve a acceptable result, you have to do depth sorting, and render EACH TRANSPARENT FACE (!!!) according to the distance to the scene camera (from furthest to nearest), and before that you render all opaque (non-transparent) faces

http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-10-transparency/
https://www.khronos.org/opengl/wiki/Transparency_Sorting#Standard_translucent

3DPrgmer
01-14-2017, 07:53 AM
well, it works, now. But how can i manage, that the transparent parts are painted AFTER the others??

Dark Photon
01-14-2017, 08:33 AM
well, it works, now. But how can i manage, that the transparent parts are painted AFTER the others??
When you're view-frustum culling your scene, you bin objects into different bins based on whether they use transparency or not. Then in your draw pass, you can draw the non-transparent (opaque) objects first.

That's one way.

john_connor
01-14-2017, 10:37 AM
if you remember what i told you in the "light" topic, "Materials" can contain additional parameters, like transparency etc. if you load a model data from files, like ".obj" model files, you can determine what face will use what material, i personally use std::map<Material, ...> to map all faces to the corresponding material, like this:

std::map<Material, std::vector<Faces>> ...

after all the model data is loaded, and before putting the vertices into your VBO, sorting all vertices is a good idea
somehow like this:


std::vector<Vertex> modeldata_opaque;
std::vector<Vertex> modeldata_transparent;

// load model ...

for each (vertex in modeldata)
{
if (material.transparency > 0.95f)
--> put it into modeldata_opaque
else
--> put it into modeldata_transparent
}

merge modeldata_opaque and modeldata_transparent later, put everything into VBO

keep track of the offset/count pair for the transparent and the opaque separately for each model
each model can then be rendered in 2 draw calls

3DPrgmer
01-15-2017, 08:12 AM
works just fine now. I have a vector with draw information (offset, size and materialindex) and when i fill that vector i check for the transparency and in that case i use pushback, otherwise pushfront. it's not the 100% solution, but it is ok for me.

Just one question do you think this is a save code??


if (segmentIterator->textureIndex < m_materials->size() && m_materials->at(segmentIterator->textureIndex).transparent)
m_drawList.push_back(new_info);
else
m_drawList.push_front(new_info);


normally if the first part is wrong the 2nd shouldn't be touched. But i'm not sure