Silhouette selection via postFx for Torque3D
by Konrad Kiss · 07/13/2009 (10:43 am) · 101 comments
This resource adds a new postFx to Torque3D that lets you have object selection with a line silhouette and an overlay. Here's an image to give you a better idea:

Before I go on with the resource, I'd like to express my thanks to those whom without I'd not been able to wrap this up now. They are:
Greg G for starting this thread.
Matt Jolly, who's made an awesome postFx, which started me on the road to figure out a lot more about shaders and postFx in T3D Beta3.
Tom Spilman for giving me glow code from Beta 3 before it was even out to be able to get started faster.
Huan Li for pointing out a change in code I couldn't find, which eventually led to this resource within a matter of hours. Also, for testing this resource!
Thanks again, guys.
One more thing, this resource does not include the method of selecting an object, only the way to render it as above. When you have your selection working, you can use this resource to make a ShapeBase to render as selected.
Alright, here we go:
0.) Don't forget to do a backup.
1.) Download the resource's files in this Torque3D only forum, and copy them into your game's source. The directory structure is the same in the zip as Torque3D's default dir structure, so you can just copy both the source and the game directory over your existing directories. No existing files should be overwritten. Don't recompile just yet.
2.) Engine source changes:
baseMatInstance.h
- Add the protected boolean mHasSelection to the BaseMatInstance class
- Also here, add the following as public methods:
// >>>
bool hasSelection() { return mHasSelection; };
void setSelection(bool sel) { mHasSelection = sel; };
// <<<matInstance.cpp
- in MatInstance::construct, set mHasSelection to false
renderPassManager.cpp
- include the new renderSelectionMgr.h
- in MeshRenderInst::clear, set mHasSelection to false
renderPassManager.h
- Add the boolean mHasSelection to the MeshRenderInst struct
sceneData.h
- Add the following to the SceneGraphData struct's BinType enum:
// >>>
/// The selection render bin.
/// @RenderSelectionMgr
SelectionBin,
// <<<shapeBase.cpp
- Insert into ShapeBase.cpp and call this method when your object's (this) selection changes. Depending on your selection method, there are different ways to handle this, but at the end, you should call this to set the selection state of the mesh.
// >>>
void ShapeBase::setSelection( bool sel )
{
if (!mShapeInstance || !isClientObject())
return;
if (!mShapeInstance->ownMaterialList())
return;
TSMaterialList* pMatList = mShapeInstance->getMaterialList();
for (S32 j = 0; j < pMatList->getMaterialInstCount(); j++)
{
BaseMatInstance * bmi = pMatList->getMaterialInst(j);
bmi->setSelection(sel);
}
}
// <<<shapeBase.h
- Add the following as a public method to the ShapeBase class definition:
// >>> void setSelection( bool sel ); // <<<
3.) Script changes:
core/scripts/client/renderManager.cs
- Add the following code to the end of the initRenderManager function:
// >>>
DiffuseRenderPassManager.addManager( new RenderSelectionMgr() { renderOrder = 1.6; processAddOrder = 1.6; } );
// <<<Now it's time to recompile.
To turn this feature on, enter SelectionPostFx.enable() at the console, and make sure you use setSelection on a ShapeBase in view.
I still want to do dynamic coloring sometime. Right now, the shader's hardwired to do a shades-of-red silhouette and overlay. If you want to change the color, here's where you'll need to make modifications in selectionShaderP.hlsl:
float4 e = float4(vis, 0, 0, vis); // <-- silhouette color float4 ovr = float4(avgval, 0, 0, avgval); // <-- overlay color ovr *= 0.4; // <-- overlay "thickness" (0.4 = 40% transparency for the overlay)
That's all. Let me know if I forgot something! (It's possible, since I just extracted this from my game. I've tried to double-check all changes, but haven't yet had the time to test it in vanilla T3D Beta 3)
Thanks for following through.
--Konrad
@konradkiss
KonradKiss @ GitHub
konradkiss.com
About the author
http://about.me/konrad.kiss
#2
07/13/2009 (7:55 pm)
You are my hero. I had to give up my pursuit of this because I had more important matters to attend to at work. You have no idea how much time you have saved me. I owe you!
#3
Yea, you really missed something as you expected, haha
That's the change in sceneData.h, you forgot the declaration of SceneGraphData::SelectionBin, which is referenced by renderSelectionManager during rendering. And that's the only thing you missed out.
07/13/2009 (9:56 pm)
Thanks, great to see it out.Quote:Let me know if I forgot something!
Yea, you really missed something as you expected, haha
That's the change in sceneData.h, you forgot the declaration of SceneGraphData::SelectionBin, which is referenced by renderSelectionManager during rendering. And that's the only thing you missed out.
#4
@Huan: Many thanks for testing this! I've updated the resource! I knew there was something! :)
07/14/2009 (6:54 am)
Thanks guys! :) I hope this will be useful!@Huan: Many thanks for testing this! I've updated the resource! I knew there was something! :)
#5
07/14/2009 (3:47 pm)
the outline is similar to what they use in Aion, looks great!!!
#6
07/14/2009 (4:48 pm)
Yeah, I agree this is absolutely fantastic. I hope this gets rolled into the base T3D.
#7
This is a great example of adding on to GFX. Nice work!
07/15/2009 (9:07 am)
I don't know about the official engine, but do you mind if I use this resource in one of my Torque 3D tutorials explaining how to expand the base engine? I want to do this for several modules: GFX, SFX, ShapeBase, etc.This is a great example of adding on to GFX. Nice work!
#8
@Jaimi: Glad to be of help. Finally, I'm giving YOU something back! :)
@Mich: Of course I wouldn't mind. I'd be honored. Thank you very much.
07/15/2009 (11:37 am)
@stadi: Thanks. I didn't know Aion had something similar! Cool.@Jaimi: Glad to be of help. Finally, I'm giving YOU something back! :)
@Mich: Of course I wouldn't mind. I'd be honored. Thank you very much.
#9
07/15/2009 (1:47 pm)
Great work, Konrad. I am really glad to see so many people getting into the guts of the Torque3D rendering so quickly. We really tried to make things easy with classes like 'RenderTexTargetBinManager'.
#10
I can definitely see that with GFX, but also with the terrain system, the new audio additions, TSShapeConstructor, and the many things that are now exposed to the console, they all make things easy. And these are things that you meet only when you pop up the hood. It feels like I'm finally in control. Many thanks for that.
07/15/2009 (2:56 pm)
Thanks Pat!Quote:
We really tried to make things easy
I can definitely see that with GFX, but also with the terrain system, the new audio additions, TSShapeConstructor, and the many things that are now exposed to the console, they all make things easy. And these are things that you meet only when you pop up the hood. It feels like I'm finally in control. Many thanks for that.
#11
07/15/2009 (3:03 pm)
Another great resource from you Konrad! I should check this section more often :D
#12
07/15/2009 (3:12 pm)
Thanks Michael! :) Wow, looks like this one attracted many of the blue people! :)
#13
07/15/2009 (4:36 pm)
Very cool Konrad, Thanks!
#14
It's really more of a tonally intense Amethyst Falls.
;P
how sad was I to try and match that ...
Great resource, though.
:)
07/16/2009 (8:35 am)
Quote:
Wow, looks like this one attracted many of the blue people!
It's really more of a tonally intense Amethyst Falls.
;P
how sad was I to try and match that ...
Great resource, though.
:)
#15
Do you have this working in Beta 5? If so, were there any changes you had to make?
08/12/2009 (11:42 pm)
@KonradDo you have this working in Beta 5? If so, were there any changes you had to make?
#16
08/13/2009 (4:15 am)
@Robert: Yes, after I ported my game to Beta 5 last night, it works fine, no changes had to be made.
#17
08/13/2009 (5:44 am)
@Konrad Thanks for the response. I must have done something wrong with my merge then. I'll go through each step more carefully again and see if I can get it working again like I did in Beta 4.
#18
Good luck, and let me know how it goes!
08/13/2009 (5:48 am)
I always do my porting the other way around - so it was adding changes made between B4 and B5. Whatever patching doesn't solve, I go through by hand. Since I didn't get a rejection on anything that would be related to the resource, and it worked fine after the port was done, I'm guessing that there's nothing extra needed for getting it to work in Beta 5.Good luck, and let me know how it goes!
#19
dynamicLight doesn't appear to be a flag in either Beta 5 or Beta 4(I may check Beta 3 later), and getMaterialInstCount doesn't exist in either version I checked either. Is there a new way of doing what's being done at those lines, or were they simply removed because nothing else was using them?
08/15/2009 (12:50 pm)
Hey, I hope you can help with this. I've decided to go an put this into Beta 5 just to see how it works, and I get these errors:1>..\..\..\source\renderInstance\renderSelectionMgr.cpp(83) : error C2039: 'dynamicLight' : is not a member of 'MeshRenderInst' 1> C:\Torque\Torque 3D 2009 Beta 5\Engine\source\renderInstance/renderPassManager.h(282) : see declaration of 'MeshRenderInst' 1>..\..\..\..\..\Engine\source\T3D\shapeBase.cpp(4251) : error C2039: 'getMaterialInstCount' : is not a member of 'TSMaterialList' 1> C:\Torque\Torque 3D 2009 Beta 5\Engine\source\ts/tsShape.h(566) : see declaration of 'TSMaterialList'
dynamicLight doesn't appear to be a flag in either Beta 5 or Beta 4(I may check Beta 3 later), and getMaterialInstCount doesn't exist in either version I checked either. Is there a new way of doing what's being done at those lines, or were they simply removed because nothing else was using them?
#20
As for the second problem, please add this to the MaterialList class as a public declaration:
Good luck, let me know if this helped!
08/17/2009 (10:44 pm)
@Bryan: Please check your PostEffect declaration for SelectionPostFx, it should be something like this:singleton PostEffect( SelectionPostFX )
{
renderTime = "PFXAfterDiffuse";
shader = PFX_SelectionShader;
stateBlock = PFX_DefaultSelectionStateBlock;
texture[0] = "#selection";
texture[1] = "$backBuffer";
target = "$backBuffer";
};As for the second problem, please add this to the MaterialList class as a public declaration:
// >>>
U32 getMaterialInstCount() const { return (U32)mMatInstList.size(); }
// <<<Good luck, let me know if this helped!

Associate OmegaDog