Flickering Entities and Alpha Values (w/ solution)
BlitzMax Forums/MiniB3D Module/Flickering Entities and Alpha Values (w/ solution)
| ||
Hi miniB3D fans! I recently had a problem with miniB3D, where I was creating many (about 50) entities from a single Mesh, each with their own rotation, etc. I was also implementing a line-of-sight algorithm with an alpha added by way of EntityAlpha n:float. I was getting a problem where my entities were flashing randomly, and the alpha was not being set properly. My first step was to force Alpha Blending by way of EntityFX 32. This resulted in my mesh fading in/out properly, but I had major z-ordering issues, since it was not enabling the opengl Depth Mask flag. After further attempts, i came upon a solution: In TMesh.bmx: ' take into account auto fade alpha alpha#=alpha#-fade_alpha# ' if surface contains alpha info, enable blending 'If surf.alpha_enable=True If alpha_order<>0.0 glEnable(GL_BLEND) glDepthMask(GL_FALSE) Else glDisable(GL_BLEND) glDepthMask(GL_TRUE) EndIf For some reason, surf.alpha_enable was invalid. The reason is because when using CopyEntity with a mesh, surfaces are not replicated, but rather they all use the same surface (see under TMesh). THUS, all entities are using the same surf.alpha_enable. SOLUTION: Instead, use alpha_order, which is kept individual to each TEntity and set during the entity list creation. I think others have had this problem, so I hope this helps all and updated to miniB3D. Last edited 2011 |
| ||
Great find! well reasoned cause and resolution, please submit to the small fixe's thread, I think this should be implemented. |
| ||
Sorry, I would take this one step further and here why: in TMesh.bmx: 'If surf.alpha_enable=True If alpha_order<>0.0 If brush.alpha#<1.0 ''the entire entity glEnable(GL_BLEND) glDepthMask(GL_FALSE) ElseIf surf.alpha_enable=True ''just one surface glEnable(GL_BLEND) glDepthMask(GL_FALSE) Else ''entity flagged for alpha, but not this surface glDisable(GL_BLEND) glDepthMask(GL_TRUE) EndIf Else glDisable(GL_BLEND) glDepthMask(GL_TRUE) EndIf Seems complex, but here's my reasoning: The first check is if there's an alpha order to be concerned about, if not, render as usual. If there is an alpha, let's check the ENTITY first, to see if there's an alpha. If not, then we check for a surface. If it's not a surface, but the mesh is flagged for alpha, then render this surface with the depthmask (opaque). This allows for separate surfaces to have an alpha value, while also allowing for full entity fades. This results in a limitation which is that we cannot have an entity that uses transparency(ie glass) and have the entire entity fade out with the glass remaining at that transparency level. To do that, we would need a separate entity copy that was exclusively transparent or a separate mesh. Nor could you have multiple entity copies where a surface fades out for that specific entity-- the workaround would be to create separate Mesh Copies. *WHEW!* Last edited 2011 Last edited 2011 Last edited 2011 |
| ||
Hello AdamRedwoods, This is what I did to correct the issues I was having with blending and the Z-ordering... alpha#=alpha#-fade_alpha# If surf.alpha_enable=True glEnable(GL_BLEND) glDepthMask(GL_FALSE) Else glDisable(GL_BLEND) EndIf ' blend modes Select blend Case 0 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ' alpha Case 1 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ' alpha Case 2 glBlendFunc(GL_DST_COLOR,GL_ZERO) ' multiply Case 3 glBlendFunc(GL_SRC_ALPHA,GL_ONE) ' additive and alpha End Select glDepthMask(GL_TRUE) Last edited 2011 Last edited 2011 |
| ||
Thanks, although my problem was directly related to the "surf.alpha_enable" variable, since I was using many instances of a single mesh with independent alpha values. My code above fixed those problems. |