Greyscale shader with object highlighting (PostFX)
by Jack Stone · 07/01/2014 (7:27 pm) · 13 comments
This resource is a very useful addition for highlighting objects using a PostFX shader.
When turned on, the screen will change to black and white, except for designated objects which will appear as bright red.
This could be used for night vision, thermal vision, highlighting objectives or special items in a game, highlighting ammunition or health pickups, etc.
The effect can be switched on and off at will.
More Images can be seen here:
http://phoenixgamedevelopment.com/blog/?p=727
The way this system works is by setting the diffuse color of the objects to be highlighted to pure red, by using this line:
%mat.diffuseColor[0] = " 255 0 0 255 " ;
and then searching for that specific color in the shader by using this line:
if(ret.r > 0.98 && ret.g < 0.09){
When it is found, that pixel is set to red, while the rest are set to black and white. This is essentially a " green screen "; type concept. As long as no other object in the game has exactly the same colour that the shader is replacing, this should work well.
A limitation of the system is that the selection of objects is done per material, not per object. Which means that multiple instances of the same object, which share the same material, will either be all highlighted or not highlighted at all. To circumvent this, it is possible to just create two version of the same object, with the same texture, but two different materials. Then, highlight one, but not the other.
Another possible limitation is that when using the " selected = 1; " dynamic variable to select multiple objects, objects inside a simgroup will not be highlighted unless there is another object sharing the same material outside the simgroup.
To implement this resource, first download the code file from here: (2KB, .rar file).
http://www.phoenixgamedevelopment.com/downloads/ObjectHighlightingResource.rar
Place the shaders " objectshighlightP.hlsl " and " objecthighlightV.hlsl " into:
shaders/common/postFx
Place " ObjectHighlightingPostEffect.cs " into:
" scripts/client/postFX/ "
Place " ObjectHighlighting.cs " into:
" scripts/server "
and execute is from " scripts/server/scriptExec.cs " by calling:
exec( " ./objecthighlighting.cs " );
Using the effect is simple.
To highlight a single object, call:
enableselection(%obj);
and to switch back to regular vision call:
disableselection(%obj);
A more useful way to use this would be to add a dynamic variable called " selected " with a value of " 1 " to a group of objects in your scene. This can be done using the mission editor, or by calling: " %obj.selected = 1; " Bearing in mind, as mentioned before, that highlighting is done per-material, not per object.
Then, simply call:
enableselectionall(); and disableselectionall();
To enable and disable the effect.
When turned on, the screen will change to black and white, except for designated objects which will appear as bright red.
This could be used for night vision, thermal vision, highlighting objectives or special items in a game, highlighting ammunition or health pickups, etc.
The effect can be switched on and off at will.
More Images can be seen here:
http://phoenixgamedevelopment.com/blog/?p=727
The way this system works is by setting the diffuse color of the objects to be highlighted to pure red, by using this line:
%mat.diffuseColor[0] = " 255 0 0 255 " ;
and then searching for that specific color in the shader by using this line:
if(ret.r > 0.98 && ret.g < 0.09){
When it is found, that pixel is set to red, while the rest are set to black and white. This is essentially a " green screen "; type concept. As long as no other object in the game has exactly the same colour that the shader is replacing, this should work well.
A limitation of the system is that the selection of objects is done per material, not per object. Which means that multiple instances of the same object, which share the same material, will either be all highlighted or not highlighted at all. To circumvent this, it is possible to just create two version of the same object, with the same texture, but two different materials. Then, highlight one, but not the other.
Another possible limitation is that when using the " selected = 1; " dynamic variable to select multiple objects, objects inside a simgroup will not be highlighted unless there is another object sharing the same material outside the simgroup.
To implement this resource, first download the code file from here: (2KB, .rar file).
http://www.phoenixgamedevelopment.com/downloads/ObjectHighlightingResource.rar
Place the shaders " objectshighlightP.hlsl " and " objecthighlightV.hlsl " into:
shaders/common/postFx
Place " ObjectHighlightingPostEffect.cs " into:
" scripts/client/postFX/ "
Place " ObjectHighlighting.cs " into:
" scripts/server "
and execute is from " scripts/server/scriptExec.cs " by calling:
exec( " ./objecthighlighting.cs " );
Using the effect is simple.
To highlight a single object, call:
enableselection(%obj);
and to switch back to regular vision call:
disableselection(%obj);
A more useful way to use this would be to add a dynamic variable called " selected " with a value of " 1 " to a group of objects in your scene. This can be done using the mission editor, or by calling: " %obj.selected = 1; " Bearing in mind, as mentioned before, that highlighting is done per-material, not per object.
Then, simply call:
enableselectionall(); and disableselectionall();
To enable and disable the effect.
About the author
#2
07/02/2014 (9:51 am)
Ah, yes, I just noticed that, thanks! I seem to have it sorted out now. I edited the resource because my preview image wasn't showing up, is there a bug with that too, do you know?
#3
07/03/2014 (7:06 am)
For some reason blogs/resources don't like being edited after posting ... no problems with actual forum threads though. After the last webdev they sent in was devoured by the Mighty Cthulhu I think GG are unwilling to sacrifice any more. ;)
#4
07/04/2014 (10:11 am)
This site is an unholy terror - I remember seeing the look in those guys' eyes....
#5
07/04/2014 (4:05 pm)
Alright, it will have to do as it is then. Would have looked better with a preview image, but never mind!
#6
Many thanks for sharing!
07/08/2014 (6:24 am)
This is cool Jack, I might have an application for this :)Many thanks for sharing!
#7
07/08/2014 (11:26 am)
Why can't this be made into a per object kind of script? That would be suitable for many other applications too. Not so?
#8
07/08/2014 (1:02 pm)
I'm sure it could, Frank - have at it!
#9
So I loaded everything in to give it a try, and the red highlighting works perfectly as advertised :)
The only thing is, I don't see the greyscale postfx and get these errors in the console:
GFXD3D9Shader::_compileShader - Error compiling shader: E_FAIL: An undetermined error occurred (80004005)
C:/Torque/Torque 3D-3.0/My Projects/GambitVR/game/shaders/common/postFx/objecthighlightV.hlsl(21,52): error X3004: undeclared identifier 'rtParams0'
C:/Torque/Torque 3D-3.0/My Projects/GambitVR/game/shaders/common/postFx/objecthighlightV.hlsl(21,16): error X3017: 'viewportCoordToRenderTarget': cannot implicitly convert from 'float2' to 'float4'
Also, I had to put the new postfx file in core/scripts/client/postfx with the existing postfx - I didn't have a postfx folder in scripts/client and when I created it and put the file there it didn't pick it up. But seems ok now that it's in the core.
Ideas on the shader error? Shaders have always been a complete mystery to me, I have only a rudimentary idea of how they work sadly lol. I know we have an extra shader or two in our game for the Oculus Rift support and maybe some AFX-related ones, is there anything special I have to do, to integrate this new one?
Thanks
P
07/09/2014 (8:08 am)
This looks really nice...So I loaded everything in to give it a try, and the red highlighting works perfectly as advertised :)
The only thing is, I don't see the greyscale postfx and get these errors in the console:
GFXD3D9Shader::_compileShader - Error compiling shader: E_FAIL: An undetermined error occurred (80004005)
C:/Torque/Torque 3D-3.0/My Projects/GambitVR/game/shaders/common/postFx/objecthighlightV.hlsl(21,52): error X3004: undeclared identifier 'rtParams0'
C:/Torque/Torque 3D-3.0/My Projects/GambitVR/game/shaders/common/postFx/objecthighlightV.hlsl(21,16): error X3017: 'viewportCoordToRenderTarget': cannot implicitly convert from 'float2' to 'float4'
Also, I had to put the new postfx file in core/scripts/client/postfx with the existing postfx - I didn't have a postfx folder in scripts/client and when I created it and put the file there it didn't pick it up. But seems ok now that it's in the core.
Ideas on the shader error? Shaders have always been a complete mystery to me, I have only a rudimentary idea of how they work sadly lol. I know we have an extra shader or two in our game for the Oculus Rift support and maybe some AFX-related ones, is there anything special I have to do, to integrate this new one?
Thanks
P
#10
@Frank: The reason why this is per material is because I am changing the properties of the material (to a fixed colour) in order to provide something for the shader to "detect" and replace.
In order to make this per object, you would need to make the material per-object as well, or at least the "diffuse color" property. This could be done, I believe I have seen some resources that could be used to do this, but since I don't need it for my current project, I didn't implement it.
It could end up being a non-trivial amount of work.
@Paul:
Based on those errors, I think I may have left two declarations out of the objecthighlightV.hlsl file. I was trimming out some non-essential code I was playing with, and I may have trimmed out too much.
Can you add these lines:
uniform float4 rtParams0;
uniform float2 oneOverTargetSize;
Just AFTER:
struct Pixel
{
float4 position : POSITION;
float2 tcColor0 : TEXCOORD0;
};
and just before "Pixel main", out side the brackets. Let me know if this works, and I can update the code file on my site.
If it still doesn't work, can you tell which version of T3D you are using, and the kind of graphics card you are using?
Having extra shaders in there wouldn't make any difference, but if you have a different folder system you could be using a different version of T3D?
07/10/2014 (4:01 pm)
Thanks a lot guys, for the compliments!@Frank: The reason why this is per material is because I am changing the properties of the material (to a fixed colour) in order to provide something for the shader to "detect" and replace.
In order to make this per object, you would need to make the material per-object as well, or at least the "diffuse color" property. This could be done, I believe I have seen some resources that could be used to do this, but since I don't need it for my current project, I didn't implement it.
It could end up being a non-trivial amount of work.
@Paul:
Based on those errors, I think I may have left two declarations out of the objecthighlightV.hlsl file. I was trimming out some non-essential code I was playing with, and I may have trimmed out too much.
Can you add these lines:
uniform float4 rtParams0;
uniform float2 oneOverTargetSize;
Just AFTER:
struct Pixel
{
float4 position : POSITION;
float2 tcColor0 : TEXCOORD0;
};
and just before "Pixel main", out side the brackets. Let me know if this works, and I can update the code file on my site.
If it still doesn't work, can you tell which version of T3D you are using, and the kind of graphics card you are using?
Having extra shaders in there wouldn't make any difference, but if you have a different folder system you could be using a different version of T3D?
#11
Running a custom engine build based on T3D 3.0, with AFX rolled in as well as winterleaf's OneWorld for client world editing... I think the targetviewport error may be related to some other thing we added for oculus rift support and/or GUI on textures resource, but I'm not sure.
Not critical, the highlighting works great, just not the grey shader :)
07/11/2014 (2:13 pm)
Great, that worked to get rid of those errors, but now I'm getting another error, something about not recognizing targetviewport...Running a custom engine build based on T3D 3.0, with AFX rolled in as well as winterleaf's OneWorld for client world editing... I think the targetviewport error may be related to some other thing we added for oculus rift support and/or GUI on textures resource, but I'm not sure.
Not critical, the highlighting works great, just not the grey shader :)
#12
From Post: http://www.garagegames.com/community/blogs/view/22773:
I had some problem implementing this ressource to T3D v3.6.3. I had to make some changes to the scripts and the shader.
Script changes:
%mat=%obj.gettargetname(%i); return only the target. I added the getMaterialMapping to get the material:
Missing samplerNames in GrayScaleShaderSD:
in objecthighlightP.hlsl
in objecthighlightV.hlsl
With those changes it work like a charm. Thanks
03/01/2015 (5:23 pm)
I have post my fixes in the other Blog post for this ressource, I will repost them here even if some fixes are listed above.From Post: http://www.garagegames.com/community/blogs/view/22773:
I had some problem implementing this ressource to T3D v3.6.3. I had to make some changes to the scripts and the shader.
Script changes:
%mat=%obj.gettargetname(%i); return only the target. I added the getMaterialMapping to get the material:
%target=%obj.gettargetname(%i); %mat = getMaterialMapping(%target);
Missing samplerNames in GrayScaleShaderSD:
singleton ShaderData( GrayScaleShaderSD )
{
DXVertexShaderFile = "shaders/common/postFx/objecthighlightV.hlsl";
DXPixelShaderFile = "shaders/common/postFx/objecthighlightP.hlsl";
***ADD START***
samplerNames[0] = "$inputTex";
***ADD END***
pixVersion = 3.0;
};Shader changes: I needed to add the declarations for variables.in objecthighlightP.hlsl
#include "./postFx.hlsl" ***ADD START*** uniform float4 targetViewport; ***ADD END*** float4 main( PFXVertToPix IN, uniform sampler2D inputTex : register(S0) ) : COLOR [...]
in objecthighlightV.hlsl
#include "./postFx.hlsl"
#include "./../torque.hlsl"
***ADD START***
uniform float4 rtParams0;
uniform float oneOverTargetSize;
***ADD END***
struct Vert
{
float4 pos : POSITION;
float2 tc : TEXCOORD0;
};With those changes it work like a charm. Thanks
#13
01/08/2018 (7:26 am)
Can you post a link to the files please? 
Associate Steve Acaster
[YorkshireRifles.com]
But you've fallen foul of the blog/resource editing bug ... when you edit a resource it turn " into &"e; ... this has to be cleaned up manually unfortunately ...