Flickering Entities and Alpha Values (w/ solution)

BlitzMax Forums/MiniB3D Module/Flickering Entities and Alpha Values (w/ solution)

AdamRedwoods(Posted 2011) [#1]
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


ima747(Posted 2011) [#2]
Great find! well reasoned cause and resolution, please submit to the small fixe's thread, I think this should be implemented.


AdamRedwoods(Posted 2011) [#3]
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


FBEpyon(Posted 2011) [#4]
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


AdamRedwoods(Posted 2011) [#5]
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.