Shadows class derived from Sceneobject
by Duncan Gray · 01/29/2006 (3:35 pm) · 112 comments
Download Code File
This does not work with TGE 1.5 onwards due to the addition of TLK in TGE
IMPORTANT: File is zipped in 7zip format. Use Free ZipGenius or the actual 7zip program to unzip it.
Download version 9d
Here is the password for the file. hjgjhjFF^kjhg75DSw3whjb(753gkj&*%gkn*^33FHkNV
Summary
While working on a game I realized that it lacked shadow detail to help add that extra touch of realism. The performance of the built in shadow code was poor and did not blend with the dif and terrain shadows, plus it lacked good consistent TSStatic class support.
I searched the forums and resources and got nothing that really fitted my needs so I set out to understand how TGE created shadows and see if it could be improved on. You can follow the progress here
Then here
Then here
So after all that, this resource is the result.
The files are replacements for the standard TGE 1.4 equivalents.
For a detailed explanation of how this shadow class works, I have added a TDN description here
Sumary
(1) Derived the shadow class from sceneObject class to make it scene state compatible.
(2) Made various optimizations to get the most efficient speeds possible.
(3) Added the ability to use external fake shadow bitmaps
(4) Added sun ambient light to match shadows color with terrain shadows
(5) Added a new render method to get shadows from tree foliage using AUX buffers
(6) Added pBuffer support (Windows) for those video cards which lacked AUX buffers
(7) Added a stencil buffer render method for those video cards which don't support AUX or pBuffers
(8) Added support for shadows from vehicle wheels
(9) Added support for Item class shadows
(10) Projectile shadows are also easy to add, but not done.
(11) ShapeReplicator shadows are also supported.
(12) Added FBO and true "render to texture" (very fast)
Compiler Notes
There are two new files which you need to add to your project, /platform/pbuffer.cpp and /platform/pbuffer.h
Version 8 adds /platform/framebuffer.h and platform/framebuffer.cpp
Design Considerations
Shadow positioning and production speed is heavily dependent on the bounding box being a good fit to the object. Make sure your bounding box does not waste too much space around the object. On the other extreme, if its too small, the shadow can appear clipped.
Texture Considerations
When using AUX buffers (version 7 and prior), the shadow bitmap is created by rendering the object against a black background. All non-black sections are then used as shadow which means any pure black colors in your texture will not render a shadow.
Use RGB of 1,1,1 for black and not 0,0,0 to solve this issue.
As of version 8, you also need to make sure that textures with Alpha channels are done correctly. e.g. the texture which comes with the standard Orc has a messed up alpha channel. Part of the texture is masked out and therefore does not render a shadow. This does not mean you have to have an alpha channel, use a jpg and it will be fine as well.
Linux and Mac
Version 7 now should be working on Unix and Mac, based on changes by Joti Carroll
Version 8 uses FBO which should work fine on Mac and Linux
[edit]
version 3 contains a fix to wheeledvehicle.cc which caused the tire to render its collision hull if you only had one tire LOD and the vehicle is in motion. It's got nothing to do with shadows, I just stuck it in there as a bonus.
[edit]
version 4 contains a fix to the static shapes which did not always render the shadow due to the position data not updating in time from client to server.
[edit]
version 5 contains a fix relating to static shadows sticking to the shadow castor when moving that object in the editor. The shadow now stays on the ground as expected.
[edit]
version 6 contains a fix to get AUX buffers working on ATI cards, provided by Alberto Barbati. Note that I have been unable to verify the working of it as I use an Nvidia card. The points he raises do make sense though so hopefully this does solve the ATI problem.
[Edit]
version 7 includes Bendan Ledwich & Joti-Caroll's changes/bug fixes
[edit]
Version 8 [216k] (too big to upload) uses "Render to Texture" on pbuffer and "Frame Buffer Object" GL extentions to produce the fastest possible shadows.
This version also reduces/eliminates the terrain bleeding through shadows problem.
Much thanks to Alberto Barbati for fixing a bug in the pBuffer section.
[edit]
Version 9 makes changes to the way wheeled vehicle tires shadows are rendered. Previous versions created sepparate shadow bitmaps for each wheel and the vehicle, which caused dark overlaps in the shadows. This version draws all the wheels and the vehicle body onto the same bitmap, creating a better looking shadow and a performance boost.
I also added the ability to fade the shadow along with the object for those time when you want to fade an object from view. Item class does this a lot. When you pick up an item it usually fades from view and fades back in a while later. Now the shadow will do the same.
[edit]
Version 9d adds the FBO declares to the linux section and this resource now fully works on Linux
Please post pictures, we like to see pictures.
This does not work with TGE 1.5 onwards due to the addition of TLK in TGE
IMPORTANT: File is zipped in 7zip format. Use Free ZipGenius or the actual 7zip program to unzip it.
Download version 9d
Here is the password for the file. hjgjhjFF^kjhg75DSw3whjb(753gkj&*%gkn*^33FHkNV
Summary
While working on a game I realized that it lacked shadow detail to help add that extra touch of realism. The performance of the built in shadow code was poor and did not blend with the dif and terrain shadows, plus it lacked good consistent TSStatic class support.
I searched the forums and resources and got nothing that really fitted my needs so I set out to understand how TGE created shadows and see if it could be improved on. You can follow the progress here
Then here
Then here
So after all that, this resource is the result.
The files are replacements for the standard TGE 1.4 equivalents.
For a detailed explanation of how this shadow class works, I have added a TDN description here
Sumary
(1) Derived the shadow class from sceneObject class to make it scene state compatible.
(2) Made various optimizations to get the most efficient speeds possible.
(3) Added the ability to use external fake shadow bitmaps
(4) Added sun ambient light to match shadows color with terrain shadows
(5) Added a new render method to get shadows from tree foliage using AUX buffers
(6) Added pBuffer support (Windows) for those video cards which lacked AUX buffers
(7) Added a stencil buffer render method for those video cards which don't support AUX or pBuffers
(8) Added support for shadows from vehicle wheels
(9) Added support for Item class shadows
(10) Projectile shadows are also easy to add, but not done.
(11) ShapeReplicator shadows are also supported.
(12) Added FBO and true "render to texture" (very fast)
Compiler Notes
There are two new files which you need to add to your project, /platform/pbuffer.cpp and /platform/pbuffer.h
Version 8 adds /platform/framebuffer.h and platform/framebuffer.cpp
Design Considerations
Shadow positioning and production speed is heavily dependent on the bounding box being a good fit to the object. Make sure your bounding box does not waste too much space around the object. On the other extreme, if its too small, the shadow can appear clipped.
Texture Considerations
When using AUX buffers (version 7 and prior), the shadow bitmap is created by rendering the object against a black background. All non-black sections are then used as shadow which means any pure black colors in your texture will not render a shadow.
Use RGB of 1,1,1 for black and not 0,0,0 to solve this issue.
As of version 8, you also need to make sure that textures with Alpha channels are done correctly. e.g. the texture which comes with the standard Orc has a messed up alpha channel. Part of the texture is masked out and therefore does not render a shadow. This does not mean you have to have an alpha channel, use a jpg and it will be fine as well.
Linux and Mac
Version 7 now should be working on Unix and Mac, based on changes by Joti Carroll
Version 8 uses FBO which should work fine on Mac and Linux
[edit]
version 3 contains a fix to wheeledvehicle.cc which caused the tire to render its collision hull if you only had one tire LOD and the vehicle is in motion. It's got nothing to do with shadows, I just stuck it in there as a bonus.
[edit]
version 4 contains a fix to the static shapes which did not always render the shadow due to the position data not updating in time from client to server.
[edit]
version 5 contains a fix relating to static shadows sticking to the shadow castor when moving that object in the editor. The shadow now stays on the ground as expected.
[edit]
version 6 contains a fix to get AUX buffers working on ATI cards, provided by Alberto Barbati. Note that I have been unable to verify the working of it as I use an Nvidia card. The points he raises do make sense though so hopefully this does solve the ATI problem.
[Edit]
version 7 includes Bendan Ledwich & Joti-Caroll's changes/bug fixes
[edit]
Version 8 [216k] (too big to upload) uses "Render to Texture" on pbuffer and "Frame Buffer Object" GL extentions to produce the fastest possible shadows.
This version also reduces/eliminates the terrain bleeding through shadows problem.
Much thanks to Alberto Barbati for fixing a bug in the pBuffer section.
[edit]
Version 9 makes changes to the way wheeled vehicle tires shadows are rendered. Previous versions created sepparate shadow bitmaps for each wheel and the vehicle, which caused dark overlaps in the shadows. This version draws all the wheels and the vehicle body onto the same bitmap, creating a better looking shadow and a performance boost.
I also added the ability to fade the shadow along with the object for those time when you want to fade an object from view. Item class does this a lot. When you pick up an item it usually fades from view and fades back in a while later. Now the shadow will do the same.
[edit]
Version 9d adds the FBO declares to the linux section and this resource now fully works on Linux
Please post pictures, we like to see pictures.
About the author
#2
B--
01/29/2006 (6:14 pm)
Screen shots look like a big improvement. Any idea how much it affected performance with your configuration before and after the changes?B--
#3
01/29/2006 (7:00 pm)
Profiler shows that these shadows take about 6-8 percent of frame time. The tree shadow bitmap is only created once per LOD change so it has very little impact on performance. Vehicle and player shadows are what take up the 6-8 percent because they get created fresh with each frame.
#4
edit: shadow.cc is giving me some problems when trying to integrate it into my project, which uses TLK 1.4. The two different versions of shadow.cc are very different and there appears to be no easy way to merge them. I'll try replacing the TLK version with the one given here but I don't expect it to work very well. =)
Any suggestions on merging this with TLK 1.4?
01/29/2006 (8:32 pm)
Very nice. I've been waiting for somebody to post a solution like this =) Thank you SO much!edit: shadow.cc is giving me some problems when trying to integrate it into my project, which uses TLK 1.4. The two different versions of shadow.cc are very different and there appears to be no easy way to merge them. I'll try replacing the TLK version with the one given here but I don't expect it to work very well. =)
Any suggestions on merging this with TLK 1.4?
#5
With your terrain bleeding problem, I recall an opengl call for polygon bleeding problems: glPolygonOffset(). I dont have your code or 1.4 installed to help at all, but I just thought I would throw it out there. Here is the site I found the description of the problem from: www.opengl.org/resources/faq/technical/polygonoffset.htm
- John
02/02/2006 (12:54 pm)
I havnt been around too long here but if I had a 'hall of fame' for those kind individuals who give back resources with big impacts, you would be on my list. With your terrain bleeding problem, I recall an opengl call for polygon bleeding problems: glPolygonOffset(). I dont have your code or 1.4 installed to help at all, but I just thought I would throw it out there. Here is the site I found the description of the problem from: www.opengl.org/resources/faq/technical/polygonoffset.htm
- John
#6
02/02/2006 (3:10 pm)
@ John, Thanks for the feedback and link. I will try playing with glPolygonOffset() when I get some time, it sounds like its the way to go.
#7
02/02/2006 (3:13 pm)
@Midhir, sorry but I don't have TLK...
#8
02/06/2006 (8:46 pm)
Edit: never mind, just saw the required extensions. ;)
#9
Great work :)
[Ishbuu]
02/08/2006 (7:24 pm)
Just what I needed :) Thanky kindly, I'll check it out once I get back on my computer. Any plans on making the rest of the shadows look equally as clean as those? (the DIF shadows in particular) - also, how would you increace/decreace the shadow texture size?Great work :)
[Ishbuu]
#10
As you asked I will be more then happy to post any changes I make here.
02/11/2006 (8:35 pm)
Yeah, nice work. I'm going to read through the code when I get a chance. It's not acting as good/clean as I had hoped. I hope I can figure out exactly how you did this and improve apon it.As you asked I will be more then happy to post any changes I make here.
#11
I commented it extensively to help make sense of it.
I'm busy on my own game code so have not had time to polish this further so it would be good to get external input.
99% of the changes in the resource are in shadow.cc and shadow.h, the other code (excluding pbuffer which is new) have VERY minor changes, most consisting of removing the old shadow code.
02/11/2006 (10:09 pm)
@Matt, if you have questions on code that does not make sense, just ask and I'll try and explain it.I commented it extensively to help make sense of it.
I'm busy on my own game code so have not had time to polish this further so it would be good to get external input.
99% of the changes in the resource are in shadow.cc and shadow.h, the other code (excluding pbuffer which is new) have VERY minor changes, most consisting of removing the old shadow code.
#12
02/12/2006 (7:28 am)
Ok. I'm busy with my own game to but the stock shadow system just doesn't cut it.
#14
A few discoveries:
I noticed that whenever I have a pure black color in any of my textures it becomes transparent in the shadow for that object. I'm goint to try out a slightly less black color and see how it works unless you have any pointers.
If I scale a static dts object in the editor, its shadow only sometimes displays for an instant, when I move the model around. It seems to keep the original pre-scaled shadow size.
The only other thing (I promise) is that some shadows don't show up at all until I select the model. After that they're lookin great!
Here are a few images of the above situations: (none of the textures use transparency)
shorton.phpwebhosting.com/images/shadowTest/shadow1.jpg //notice the whiskers in this one
shorton.phpwebhosting.com/images/shadowTest/shadow2.jpg
shorton.phpwebhosting.com/images/shadowTest/shadow3.jpg
I'm running a geForce FX 5700 with latest drivers.
Once again, big round of applause for Duncan!
03/02/2006 (4:19 pm)
Duncan, you have put an amazing amount of effort into this resource and I just want to say thanks first and foremost. It seems like you should have "employee" under your name!A few discoveries:
I noticed that whenever I have a pure black color in any of my textures it becomes transparent in the shadow for that object. I'm goint to try out a slightly less black color and see how it works unless you have any pointers.
If I scale a static dts object in the editor, its shadow only sometimes displays for an instant, when I move the model around. It seems to keep the original pre-scaled shadow size.
The only other thing (I promise) is that some shadows don't show up at all until I select the model. After that they're lookin great!
Here are a few images of the above situations: (none of the textures use transparency)
shorton.phpwebhosting.com/images/shadowTest/shadow1.jpg //notice the whiskers in this one
shorton.phpwebhosting.com/images/shadowTest/shadow2.jpg
shorton.phpwebhosting.com/images/shadowTest/shadow3.jpg
I'm running a geForce FX 5700 with latest drivers.
Once again, big round of applause for Duncan!
#15
I'll look into it a bit later but I suspect the fix is in Shadow::createAdvancedShadow, just below
A texture with black data will have a luminance of zero in those areas and my formula will therefore assume that no luminance = nothing to cast a shadow from.
You will see a line if(luminance>0). This is because the shadow bitmap is created by rendering the object against a black background and assuming that anything which is not black should be casting a shadow.
I think the easiest solution is to change your texture so that the black sections are not=0 but =1, i.e. RGB=1,1,1 and everything should be fine.
[edit]
I have now added a note to the top of the resource page about not using pure black in your textures.
.
03/02/2006 (5:00 pm)
Interesting observation and it does explain some things I saw with the buggy shadow. Well spotted.I'll look into it a bit later but I suspect the fix is in Shadow::createAdvancedShadow, just below
// Technically correct shadows can be obtained by using the alpha value // when ever the luminance is above zero, but its slightly slower than the previous.
A texture with black data will have a luminance of zero in those areas and my formula will therefore assume that no luminance = nothing to cast a shadow from.
You will see a line if(luminance>0). This is because the shadow bitmap is created by rendering the object against a black background and assuming that anything which is not black should be casting a shadow.
I think the easiest solution is to change your texture so that the black sections are not=0 but =1, i.e. RGB=1,1,1 and everything should be fine.
[edit]
I have now added a note to the top of the resource page about not using pure black in your textures.
.
#16
[edit] Its fixed as of version 4
03/02/2006 (5:28 pm)
Regarding having to 1st click on a shadow, .................................[edit] Its fixed as of version 4
#17
How would I go about setting the overall transparency of the shadows? They seem quite dark.
03/02/2006 (9:10 pm)
rgb 1 1 1 works like a charm!How would I go about setting the overall transparency of the shadows? They seem quite dark.
#18
It was done so that dts shadows will exactly match the darkness of diff shadows.
You don't want to independently set the shadow darkness or it will look odd when you place a dts object next to a diff object in the game.
Rather adjust the ambient values of the sun to suit your game requirements.
03/02/2006 (9:47 pm)
The shadow darkness uses the sun's ambient light level as defined in the sun object in your mission file.It was done so that dts shadows will exactly match the darkness of diff shadows.
You don't want to independently set the shadow darkness or it will look odd when you place a dts object next to a diff object in the game.
Rather adjust the ambient values of the sun to suit your game requirements.
#20
03/03/2006 (12:16 pm)
Hey - I think I said this before but I would like to implament a working version of this code into my game. When I finish adding some of the things required by our mappers I am hoping I will finally be able to look at your code (and existing Torque Code) and fix thease bugs as well as make an opimazation or two. Hopefully I can get started by Wensday. 
Torque Owner Jason "fireVein" Culwell
-Jase