Z-ordering & shaders in Klepto's mod

BlitzMax Forums/MiniB3D Module/Z-ordering & shaders in Klepto's mod

Robb(Posted 2008) [#1]
Firstly, I'm pretty new to MiniB3d so I apologise if I'm missing something glaringly obvious but anyhow, I'm trying to create a basic material system using klepto's version of MiniB3d but I'm having issues with the z-ordering on alpha masked textures.

Currently if I load a texture with the Alpha flag, the textures are drawn over each other and I can't seem to sort the problem out.

I attempted to use a simple GLSL shader, which works fine if I use the discard function, but I cannot use the alpha channel for transparency. It works if I load the texture with the alpha flag, but again the ordering gets messed up.

This is my current code, adapted from the shader example:
Local Decal:TTexture = LoadTexture("Texture.tga")
tex.BrushTexture(Decal,0)

BrushShaderTexture(Tex,Decal , 0)

InitShader(Tex)
AddShaderObject(Tex,"media/new.vert","media/new.frag")
Tex.ProgramAttriBegin()
	Tex.SetUI1("texture" , 0) 
Tex.ProgramAttriEnd()

PaintEntity(mesh, Tex)
ActivateShader(mesh, True)


This is my vert shader:
void main()
{
	gl_Position = ftransform();
	gl_TexCoord[0] = gl_MultiTexCoord0;
}


this is my frag shader:
uniform sampler2D texture;

void main()
{
	vec4 texColor = texture2D(texture, gl_TexCoord[0].st);
	gl_FragColor = texColor;
}


Anyone have any suggestions? Thanks!


klepto2(Posted 2008) [#2]
The problem is related to the entity system.

At first you have to set up your entitys fx and entity blend modes to enable all features with glsl as you've seen with the
texture flags. No the problem occurs: glsl fragments are underlying the same rule as normal non glsl processed meshes.
Lets take your example:
You create your mesh and assign the shader. The mesh itself has no alpha so minib3d doesn't sort it. One solution would be to simply set blending to alphablend and to set the alpha value to the same value as you do in the shader.

The problem is that minib3d only compare normal brush textures but shadertextures are not handles during the rendering process.

The new extended will have a completely new and independend Shadersystem which will handle theseissues automatically but until release I think setting EntityAlpha should do the trick.


Robb(Posted 2008) [#3]
Thanks for the reply, though I'm still not having any luck :-(

Totally forgetting about using GLSL for a moment, I put together a test using only a cube mesh and the basic MiniB3D commands and i'm still getting this effect:



I have specified alphablend on the entity, the texture and the brush as well as setting all of them to have an alpha value of 1. I also set the entityfx to disable backface culling but as soon as the texture is loaded with the alpha flag it starts drawing things on top of each other.

Am I still missing the point here or is something else going on?


klepto2(Posted 2008) [#4]
could you maybe post a small sample or host a small demo with this issue?


Robb(Posted 2008) [#5]
This is the test app I used. When it requests a file, choose a texture with an alpha channel. Actually, even if you choose one without an alpha channel the error will still occur.

Import klepto.minib3d
Strict

Graphics3D 1024,768,32,0

Local cam:TCamera=CreateCamera()
CameraRange cam,.5,500
PositionEntity cam,0,10,-100

AmbientLight 100,100,100

Local mesh:TMesh=CreateCube()
EntityFX mesh,16
ScaleEntity mesh,10,10,10

EntityBlend mesh,1
EntityAlpha mesh,1

'Load any alphamapped texture
Local texture:TTexture=LoadTexture(RequestFile("Texture"),2)
TextureBlend texture,1

Local Tex:TBrush=CreateBrush()
BrushTexture(tex,texture)
BrushBlend tex,1
BrushAlpha tex,1
PaintMesh mesh,tex

' used by camera code
Local mxs#=0
Local mys#=0
Local move#=0.5
MouseXSpeed() ' flush
MouseYSpeed() ' flush

' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps

Local W:Byte = False

While Not KeyDown(KEY_ESCAPE)		

	If KeyHit(KEY_ENTER) Then DebugStop
	
	If KeyHit(Key_W) Then 
		Wireframe(Not W)
		W = Not W
	EndIf

	mxs#=mxs#+(MouseXSpeed()/5.0)
	mys#=mys#+(MouseYSpeed()/5.0)

	RotateEntity cam,mys#,-mxs#,0

	MoveMouse 1024/2,768/2
	MouseXSpeed() ' flush
	MouseYSpeed() ' flush

	
	If KeyDown(KEY_UP)=True Then MoveEntity cam,0,0,move# ' move camera forward
	If KeyDown(KEY_DOWN)=True Then MoveEntity cam,0,0,-move# ' move camera back

	If KeyDown(KEY_LEFT)=True Then MoveEntity cam,-move#,0,0 ' move camera left
	If KeyDown(KEY_RIGHT)=True Then MoveEntity cam,move#,0,0 ' move camera right
	
	UpdateWorld
	RenderWorld

	Flip
	
Wend
End



klepto2(Posted 2008) [#6]
If you're able to rebuild the mod then try the following:

Open 'TMesh.bmx' and go to the TMesh.Update() Method.

Find this piece of code:
If Self.Alpha(surf)=True
				glEnable(GL_BLEND)
				glDepthMask(GL_FALSE)
			Else
				glDisable(GL_BLEND)
				glDepthMask(GL_TRUE)
			EndIf


and replace it with :
If Self.Alpha(surf)=True
				glEnable(GL_BLEND)
				'glDepthMask(GL_FALSE)
			Else
				glDisable(GL_BLEND)
				glDepthMask(GL_TRUE)
			EndIf


I don't know how it will affact other blendmodes but atleast the z-order problem should be solved.


Robb(Posted 2008) [#7]
Thanks for all the help on this.

I tried what you suggested and though the module compiled properly the problem doesn't seem to be fixed, only a bit different. Now some alpha faces are in the correct order but others have no alpha at all and obscure the rest of the mesh. Hmmm :-S


Ross C(Posted 2008) [#8]
I think this is an alpha issue in general. Whenever you get two alpha values on the z-buffer they fail to have any order because they are being blended based on what's in front / behind.