Alphablend in ModelDrawer.cs

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
chronicacid
Posts: 12
Joined: Sat Jul 10, 2010 5:19 pm

Alphablend in ModelDrawer.cs

Post by chronicacid »

How can I properly use Alphablend in the ModelDrawer.cs to display my .png files to preserve transparency.

If i turn off depthbuffer and leave Alphablend on - it looks perfect - that is the .png transparency (leaves on a tree)

but everything else on the other models in the simulation looks awkward.

Can you assist me with getting this to render correctly ?

I'm using the latest version .13. I can be more descriptive if I'm not clear enough.

Thanks!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Alphablend in ModelDrawer.cs

Post by Norbo »

The ModelDrawer is designed as a debug drawing system. The 'instanced' version of the drawer is poorly suited to drawing transparent and nontransparent objects together since it batches everything together blindly. You could try creating two drawers and handle all the transparent geometry in the second one.

I strongly recommend against using the demos drawer as a normal game's renderer as there will likely be many more design conflicts like this one. It can draw blocks, spheres, capsules and such well, but trying to integrate more features into it will be ugly.
chronicacid
Posts: 12
Joined: Sat Jul 10, 2010 5:19 pm

Re: Alphablend in ModelDrawer.cs

Post by chronicacid »

Is the a hack fix that requires a small amount of code/movement of code that would allow me to get this to work that you might be able to assist with. My project may not require a lot of changes to the already written code - that why I'm asking.

Thanks in advance!

Your physics program is Awesome btw. I hope we can both be successful with it :)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Alphablend in ModelDrawer.cs

Post by Norbo »

The quickest and dirtiest solution I can think of off the top of my head is to have two ModelDrawers, say "opaqueModelDrawer" and "transparentModelDrawer." When creating and adding models to the drawers, add all opaque models to the opaque drawer, and add all transparent models to the transparent drawer.

Then, during the draw, draw the opaque model drawer first with the normal opaque renderstates. After that, enable transparency and draw the transparentModelDrawer.

The reason I didn't include disabling depth buffer writes was that they are needed to sort out which pixel is in front. This should work for things with 0% or 100% transparency, but does not handle partial transparency. This basically means your leaves have to have hard edges, so it's a binary alpha test rather than alpha 'blending.'

There are other, fancier, better ways of dealing with this issue, which Shawn Hargreaves explains better than I could: http://blogs.msdn.com/b/shawnhar/archiv ... jects.aspx

If you need to implement something a little fancier, you could look into the drawer's SelfDrawingModelDisplayObject which manages its own drawing completely. Of course, you can always use the drawer for what it can do, and custom implementations for what it cannot.
Your physics program is Awesome btw. I hope we can both be successful with it :)
Thanks!
chronicacid
Posts: 12
Joined: Sat Jul 10, 2010 5:19 pm

Re: Alphablend in ModelDrawer.cs

Post by chronicacid »

Just wanted to say thanks for the Tips on this.
Marvin
Posts: 32
Joined: Wed Aug 04, 2010 9:16 pm

Re: Alphablend in ModelDrawer.cs

Post by Marvin »

hey this might help you.

in phone game i use this:

modelDrawer.draw(camera.viewMatrix, camera.projectionMatrix);
// lineDrawer.draw(camera.viewMatrix, camera.projectionMatrix);

//DRAW MODEL
drawModel(VehicleInput.snowBoard, Matrix.CreateTranslation(0, -1.2f, 0), VehicleInput.snowBoardTexture, true);
drawModel(VehicleInput.snowBoarder, Matrix.CreateScale(0.4f) * Matrix.CreateFromYawPitchRoll(0, -(float)Math.PI / 2, 0) * Matrix.CreateTranslation(0, -1.2f, 0), VehicleInput.shadowTexture, true);


//DRAW SHADOWS
GraphicsDevice.BlendState = BlendState.AlphaBlend;
drawShadow(VehicleInput.snowBoard, VehicleInput.snowBoardShadow, false, 0.25f);
drawShadow(VehicleInput.snowBoarder, VehicleInput.snowBoarderShadow, false, 0.25f);
GraphicsDevice.BlendState = BlendState.Opaque;


the shadows obviously need alpha blending, so i wrote my own drawer classes, which are the following:
it works really well for me, having these seperate classes to draw the diffrent stuff you want to draw. Make sure you draw all the transparant stuff at the end, the opaque stuff first!

(WorldTransForm is a copy of the vehicleinput.vehicle.body.worldtransform a public static matrix I use to pass it to the drawer to make it "stick" to the moving entity's).

good luck

public void drawMap(Model myModel)
{
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);

// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in myModel.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.PreferPerPixelLighting = true;
effect.LightingEnabled = true;
effect.DirectionalLight0.Enabled = true;
effect.DirectionalLight0.Direction = Vector3.Normalize(Light);
effect.DirectionalLight0.DiffuseColor = new Vector3(.5f, .5f, .5f);
effect.AmbientLightColor = new Vector3(.5f, .5f, .5f);
// effect.SpecularColor = new Vector3(0.8f, 0.8f, 0.6f);
// effect.SpecularPower = 16;
effect.TextureEnabled = true;

effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(new Vector3(0, 0, 0));
effect.View = camera.viewMatrix;
effect.Projection = camera.projectionMatrix;
effect.Alpha = 1f;

}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
public void drawModel(Model myModel, Matrix orientMatrix, Texture2D setTexture, bool SticksToSnowboard)
{
if (SticksToSnowboard == true)
{
orientMatrix = orientMatrix * VehicleInput.WorldTransForm;
}
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);

// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in myModel.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.PreferPerPixelLighting = true;
effect.LightingEnabled = true;
effect.DirectionalLight0.Enabled = true;
effect.DirectionalLight0.Direction = Vector3.Normalize(Light);
effect.DirectionalLight0.DiffuseColor = new Vector3(.5f, .5f, .5f);
effect.AmbientLightColor = new Vector3(.5f, .5f, .5f);
// effect.SpecularColor = new Vector3(0.8f, 0.8f, 0.6f);
// effect.SpecularPower = 16;
effect.TextureEnabled = true;

effect.World = transforms[mesh.ParentBone.Index] * orientMatrix;
effect.View = camera.viewMatrix;
effect.Projection = camera.projectionMatrix;
effect.Alpha = 1f;
effect.Texture = setTexture;

}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
}
public void drawShadow(Model myModel, Matrix orientMatrix, bool SticksToSnowboard, float alpha)
{
if (SticksToSnowboard == true)
{
orientMatrix = orientMatrix * VehicleInput.WorldTransForm;
}
Texture2D TempTexture = null;
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);

// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in myModel.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.PreferPerPixelLighting = true;
effect.LightingEnabled = false;
effect.DirectionalLight0.Enabled = false;
effect.DirectionalLight0.Direction = Vector3.Normalize(Light);
effect.DirectionalLight0.DiffuseColor = new Vector3(.5f, .5f, .5f);
effect.AmbientLightColor = Vector3.Zero;

TempTexture = effect.Texture;

effect.TextureEnabled = true;
effect.Texture = VehicleInput.shadowTexture;
effect.World = transforms[mesh.ParentBone.Index] * orientMatrix;
effect.View = camera.viewMatrix;
effect.Projection = camera.projectionMatrix;
effect.Alpha = alpha;

}
// Draw the mesh, using the effects set above.
mesh.Draw();
foreach (BasicEffect effect in mesh.Effects)
{
effect.Texture = TempTexture;
}
}
}
chronicacid
Posts: 12
Joined: Sat Jul 10, 2010 5:19 pm

Re: Alphablend in ModelDrawer.cs

Post by chronicacid »

Marvin - Thank you for your response! I appreciate it very much. I have been so focused on assets for my game in last few weeks that I forgot to check back in the thread for updates. Thanks again!
Post Reply