Skylight for Torque 3D
by Nils Eikelenboom · 01/22/2014 (4:56 am) · 17 comments
On a sunny day while standing in the shadow, you'll notice that a blue sky is actually emitting light. I was looking for a solution to add skylight to Torque 3D beside the use of ambient light with advanced lighting. The stock ambient light is not sufficient to imitate the light emitting sky.
Since I'm not very good in writing shaders (not at all), did I came up with a very simple but effective solution: create a 2nd light source next to the sun object. A 2nd sun object is not an option, as it doesn't work as it should, and no spotlight can be big enough to light up entire scene of several square km's. If you mount a light to the player you'll have the advantage of keeping the radius small and emit light in a direction that looks like it's everywhere around, as long as the light object is high enough:

You can see in the image above that it's obvious that you if have objects in your mission that are higher then around 12 meters, you should increase the radius and mount the light object higher above the player.
By adding another light source, next to the Sun object, you'll increase lighting of shadows. This will have the great side effect of normals that were otherwise hardly visible in the dark shadows are now popping out!

[+] click to enlarge
Note: This resource is meant for own implementation. I use this for a single player adventure game with changed source code and scripts. It's not tested with T3D MIT 3.5 and over network. The code below is just an example how to implement this!!!
At the end of scrips/server/Player.cs
The colour in the example is blue, but you could turn it into a var and make it for perhaps the same as your "canvas clear colour". The shadows are turned off of the sake of fps.
I have a separate server script for environment stuff, so I put in in there.
Of course you can put it somewhere else as long as it is executed with scriptExec.cs
Name you sun object in your missions "TheSun" if you're using the following code:
in scrips/server/Enviroment.cs
You can turn on the skylight when player is entering the game. I created custom game types, in this case "AdventureGame", and only turn it on when needed. You can create a copy of deathMatch.cs and make sure it's executed with scriptExec.cs
in yourGameType.cs
But of course are there other/better ways to do this! I'm not a coder so tips and fixes are surely welcome.
Good luck!
Since I'm not very good in writing shaders (not at all), did I came up with a very simple but effective solution: create a 2nd light source next to the sun object. A 2nd sun object is not an option, as it doesn't work as it should, and no spotlight can be big enough to light up entire scene of several square km's. If you mount a light to the player you'll have the advantage of keeping the radius small and emit light in a direction that looks like it's everywhere around, as long as the light object is high enough:

You can see in the image above that it's obvious that you if have objects in your mission that are higher then around 12 meters, you should increase the radius and mount the light object higher above the player.
By adding another light source, next to the Sun object, you'll increase lighting of shadows. This will have the great side effect of normals that were otherwise hardly visible in the dark shadows are now popping out!

[+] click to enlarge
The code
Note: This resource is meant for own implementation. I use this for a single player adventure game with changed source code and scripts. It's not tested with T3D MIT 3.5 and over network. The code below is just an example how to implement this!!!
At the end of scrips/server/Player.cs
//----------------------------------------------------------------------------
// +++ Player skylight
//----------------------------------------------------------------------------
function Player::SkylightEnable(%this)
{
// spotlight
%skylight = new PointLight(SkyLightEmitter)
{
radius = "48";
isEnabled = "1";
color = "0.243137 0.509804 0.843137 1";
brightness = "0.33";
castShadows = "0";
priority = "1";
animate = "0";
animationPeriod = "1";
animationPhase = "1";
flareScale = "0";
attenuationRatio = "0 1 1";
shadowType = "Spot";
texSize = "512";
overDarkFactor = "2000 1000 500 100";
shadowDistance = "48";
shadowSoftness = "0.5";
numSplits = "1";
logWeight = "0.9";
fadeStartDistance = "0";
lastSplitTerrainOnly = "0";
representedInLightmap = "0";
shadowDarkenColor = "0 0 0 -1";
includeLightmappedGeometryInShadow = "0";
position = "0 0 0";
rotation = "0 0 0 0";
mountPID = "";
mountNode = "3";
mountPos = "0 0 0";
mountRot = "0 0 0 0";
canSave = "1";
canSaveDynamicFields = "1";
};
%this.mountobject(%skylight, 0, "0.0 0.0 24.0"); // mountobject(%obj, mountNode, mountOffset)
%this.light = %skylight;
}
//----------------------------------------------------------------------------The colour in the example is blue, but you could turn it into a var and make it for perhaps the same as your "canvas clear colour". The shadows are turned off of the sake of fps.
I have a separate server script for environment stuff, so I put in in there.
Of course you can put it somewhere else as long as it is executed with scriptExec.cs
Name you sun object in your missions "TheSun" if you're using the following code:
in scrips/server/Enviroment.cs
//----------------------------------------------------------------------------
function skyLight(%client)
{
if(isObject(TheSun))
{
%player = %client.player;
%player.SkylightEnable();
echo("Skylight enabled");
}
}
//----------------------------------------------------------------------------You can turn on the skylight when player is entering the game. I created custom game types, in this case "AdventureGame", and only turn it on when needed. You can create a copy of deathMatch.cs and make sure it's executed with scriptExec.cs
in yourGameType.cs
function yourGameType::onClientEnterGame(%game, %client)
{
parent::onClientEnterGame(%game, %client);
skyLight(%client);
}But of course are there other/better ways to do this! I'm not a coder so tips and fixes are surely welcome.
Good luck!
#2
01/22/2014 (6:00 am)
Thanks for sharing this
#3
01/22/2014 (6:32 am)
To present the "more than one way to skin a cat" option - you can raise the ambient light in your outdoor levels using the ScatterSky or Sun object's properties. If you have caves (like the Pacific demo) then you can use triggers to procedurally alter the ambient light level.
#4
Skylight off:

[+] Enlarge
Skylight on:

[+] Enlarge
But for multiplayer I would go indeed for raised ambient light levels, or find a way to do this on the client side only.
01/22/2014 (8:34 am)
@Richard; Ambient light is not directional and looks quite different from "Skylight" which is directional. The following screenshots show the difference; the 1st without and the 2nd with skylight. Both shots are with ambient light...Skylight off:

[+] Enlarge
Skylight on:

[+] Enlarge
But for multiplayer I would go indeed for raised ambient light levels, or find a way to do this on the client side only.
#5
In Airship Dragoon I actually have a real low level light placed at the opposite XY side of the sun and set to cover the whole map without any falloff or shadowing as a way of picking up a slight reflection on the specular and normal maps in ambient shadow to prevent the diffuse from looking totally flat where sunlight does not reach it.
... reads that back to himself to check it made sense ...
01/22/2014 (9:57 am)
That's quite cool, Nils.In Airship Dragoon I actually have a real low level light placed at the opposite XY side of the sun and set to cover the whole map without any falloff or shadowing as a way of picking up a slight reflection on the specular and normal maps in ambient shadow to prevent the diffuse from looking totally flat where sunlight does not reach it.
... reads that back to himself to check it made sense ...
#6
01/22/2014 (2:20 pm)
I tried this for night time scenes in my demo but one thing i was concerned about was weird shadows when running though the forest and a perform,ance drop did this happen with you?
#7
01/22/2014 (2:25 pm)
in the end i thought it might take out of the realism so i thought of making a pet that emitted light for night scenes to add more of a environmental element to the lighting.
#8

________________________________________________________________________
@Kevin; For night time scenes you'll need to tune down the brightness; I don't know if it would be still worth it. I had the best results with shadows off. The performance drop is then hardly noticeable. Light emitting pet? Perhaps you can you use AI mounted in a (invisible) flying vehicle with a light object attached...
01/22/2014 (6:31 pm)
@Steve; Yes it makes sense! That would work for multiplayer and not-too-big maps. The downside with that is the angle of the light source is different with every position in the world and illuminates only from one side. If the light source follows the player you'll eliminate that...
________________________________________________________________________
@Kevin; For night time scenes you'll need to tune down the brightness; I don't know if it would be still worth it. I had the best results with shadows off. The performance drop is then hardly noticeable. Light emitting pet? Perhaps you can you use AI mounted in a (invisible) flying vehicle with a light object attached...
#9
Ron showed this in his blog a while ago: www.garagegames.com/community/blogs/view/22307
At the beginning of his video he shows the difference between normal lighting and single bouncing lighting.
01/23/2014 (1:40 am)
I think a bouncing light would help too, will cost some performance.Ron showed this in his blog a while ago: www.garagegames.com/community/blogs/view/22307
At the beginning of his video he shows the difference between normal lighting and single bouncing lighting.
#10
Duion, you are right about a bouncing light but what Ron did was a shader.
At the beginning of the post Nils said he isn't that good at creating shaders.
It's a great hack and work around for those that aren't that good at writing shaders.
EDIT: At least for single player games!
01/23/2014 (3:16 am)
Great resource!Duion, you are right about a bouncing light but what Ron did was a shader.
At the beginning of the post Nils said he isn't that good at creating shaders.
It's a great hack and work around for those that aren't that good at writing shaders.
EDIT: At least for single player games!
#11
01/23/2014 (9:53 pm)
The biggest drawback of this approach is that CPU consumption is not small.
#12
www.garagegames.com/community/forums/viewthread/134717
@Duion; Even if I master the art of writing shaders, I don't think I would write something for this if the solution could be much more simple. But bouncing light is nice; but I think I'd prefer that for indoor missions for a while.
@Zhu; It's a pointlight with a small radius, no shadows, and no flares and cookies etc..
CPU consumption is pretty small!
01/23/2014 (10:32 pm)
I'm sure there's a way to make this client side only and do this for multiplayer as well. Look at this thread for example: www.garagegames.com/community/forums/viewthread/134717
@Duion; Even if I master the art of writing shaders, I don't think I would write something for this if the solution could be much more simple. But bouncing light is nice; but I think I'd prefer that for indoor missions for a while.
@Zhu; It's a pointlight with a small radius, no shadows, and no flares and cookies etc..
CPU consumption is pretty small!
#13
I like it. It's a nice alternative to my single bounce GI shader and it's more efficient on larger outdoor scenes. Good work! I bet this would rock once I get my IBL shader finished up....
In fact, the FPS and MSPF take a MUCH smaller hit than with my shader and it looks nearly the same. I do tend to over think things.... again though... nice work. I think I will make it stock in my builds.
Ron
01/29/2014 (3:25 pm)
Nils, I like it. It's a nice alternative to my single bounce GI shader and it's more efficient on larger outdoor scenes. Good work! I bet this would rock once I get my IBL shader finished up....
In fact, the FPS and MSPF take a MUCH smaller hit than with my shader and it looks nearly the same. I do tend to over think things.... again though... nice work. I think I will make it stock in my builds.
Ron
#14
02/03/2014 (2:01 am)
Great @Ron, glad you can use this :)
#15
03/01/2014 (6:21 pm)
Wow Nils, I didnt realise you released this as a resource, for the sheer fact it gets normals working in the shadows is awesome by itself, and a bonus that it breaks up torques monotone ambient shadowing is fantastic.
#16
It's only too bad there's not that much of it left at the moment {sigh)
03/03/2014 (6:17 am)
Happy to give it (slowly) back to the community @Andy. It's only too bad there's not that much of it left at the moment {sigh)
#17
09/23/2014 (7:58 am)
Note It's important to attach the skylight to a node on the player that has the Z fully upwards. 
Torque Owner Nils Eikelenboom
Studio DimSum