Lighting, Shadows, Techniques etc?

Mephs

28-07-2008 09:27:50

Where might I find information on lighting and shadows, maybe more specifically with MOGRE, or even OGRE is fine (something I can figure out from looking at examples and code)?

I've been trying to get shadows and lights to work on my current project but maybe I'm completely missing something, but I can't seem to get them to cast any shadows at all :?

Here's a screenie



And the code for CreateScene()

private void CreateScene()
{
scene = mRoot.CreateSceneManager(SceneType.ST_GENERIC);
pvCam = new PivotCamera(scene, 60, 150);
pvCam.SetTetherLength(90);
pvCam.SetTetherAngle(45);
pvCam.SetRotateAngle(45);
pvCam.SetTiltLimit(40, 50);
mWindow.AddViewport(pvCam.GetCamera());
pvCam.SetVisibility(0);

mRoot.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);

Entity ent = scene.CreateEntity("Map01", "Map.mesh");
ent.CastShadows = true;
scene.RootSceneNode.CreateChildSceneNode().AttachObject(ent);

//Light
Light light = scene.CreateLight("test");
light.Type = Light.LightTypes.LT_DIRECTIONAL;
light.SetDiffuseColour(.3f, 0, .3f);
light.SetSpecularColour(.3f, 0, .3f);
light.Direction = new Vector3(-1,-1,0);

light = scene.CreateLight("newtest");
light.Type = Light.LightTypes.LT_POINT;
light.SetPosition(10, 16, -100);
light.SetDiffuseColour(1, 1, 1);
light.SetSpecularColour(1, 1, 0);
light.Direction = new Vector3(1, 1, -1);


scene.ShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE;
scene.AmbientLight = new ColourValue(0.9f, 0.6f, 0.5f);

// Create SpriteManager
sprites = new SpriteManager(scene);

// Create initial sprites
Sprite spr = new Sprite("Knight2", new Vector3(3 + (6 * 4), 6, 3 - (6 * 10)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim2", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.SouthWest);
sprites.add(spr);
spr = new Sprite("Knight1", new Vector3(3 + (6 * 3), 6, 3 - (6 * 5)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim1", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.NorthEast);
sprites.add(spr);
sprites.ShowAll();
pvCam.SetVisibility(1);
}


Ideally what I'd like to accomplish is getting control over making the sprites (the two characters, which are billboards) to cast a small shadow as well as the houses, but it doesn't seem like anything wants to cast a shadow other than just the light beating against the sides of the walls/raised ground.

I've tried changing the shadow type in the SceneManager to no avail, tried all manner of moving lights around (can't even seem to get spotlights to show up, only directional and point).

I have great ideas for making this map look a lot less "bland" but I have no idea where to start, lol. If there's any resources that covers specifically this topic out there let me know, or if there's something in the Scene creation code I completely overlooked.

lilljohan

28-07-2008 10:03:19

There are some material properties for shadows. Check here http://www.ogre3d.org/docs/manual/manual_14.html#SEC23

And here is a good resource as well =) http://www.ogre3d.org/docs/manual/manual_67.html#SEC286

And if you want to go high tech. http://www.ogre3d.org/wiki/index.php/Cu ... ow_Mapping

But try modulative texture shadows first.

Edit try light.SetShadowsEnabled(true) or something similar.

Mephs

28-07-2008 15:22:39


Edit try light.SetShadowsEnabled(true) or something similar.


I'll look at some of those today :)

There is no SetShadowsEnabled property, only light.CastsShadows = true, and that doesn't seem to do anything. Would I need to set the material on that Mesh to "receive shadows" in the material script?

lilljohan

28-07-2008 16:11:00


Edit try light.SetShadowsEnabled(true) or something similar.


I'll look at some of those today :)

There is no SetShadowsEnabled property, only light.CastsShadows = true, and that doesn't seem to do anything. Would I need to set the material on that Mesh to "receive shadows" in the material script?

CastShadows = true should be the same as SetShadowsEnabled, sometimes the properties are read only didn't have time to check.

I think receive_shadows is on as default, but try it anyway.

Forgot one thing. you need to enable CastShadows on all entities that should cast shadows =)

Mephs

28-07-2008 16:25:58


Edit try light.SetShadowsEnabled(true) or something similar.


I'll look at some of those today :)

There is no SetShadowsEnabled property, only light.CastsShadows = true, and that doesn't seem to do anything. Would I need to set the material on that Mesh to "receive shadows" in the material script?

CastShadows = true should be the same as SetShadowsEnabled, sometimes the properties are read only didn't have time to check.

I think receive_shadows is on as default, but try it anyway.

Forgot one thing. you need to enable CastShadows on all entities that should cast shadows =)


ATM I have everything with CastShadows set to true, the Mesh, the billboards (billboard sets I think, actually, I didn't get a CastShadows option on the billboards themselves).

If receive shadows is on by default I don't know what else I can do :(

lilljohan

28-07-2008 17:12:56


Edit try light.SetShadowsEnabled(true) or something similar.


I'll look at some of those today :)

There is no SetShadowsEnabled property, only light.CastsShadows = true, and that doesn't seem to do anything. Would I need to set the material on that Mesh to "receive shadows" in the material script?

CastShadows = true should be the same as SetShadowsEnabled, sometimes the properties are read only didn't have time to check.

I think receive_shadows is on as default, but try it anyway.

Forgot one thing. you need to enable CastShadows on all entities that should cast shadows =)


ATM I have everything with CastShadows set to true, the Mesh, the billboards (billboard sets I think, actually, I didn't get a CastShadows option on the billboards themselves).

If receive shadows is on by default I don't know what else I can do :(

Are the houses seperate meshes? If not, disabled CastShadows on them, set receive_shadows to on in the material. I think that could be the problem, because self shadowing is only supported if you use custom shadow mapping.

Mephs

28-07-2008 17:15:40


Are the houses seperate meshes? If not, disabled CastShadows on them, set receive_shadows to on in the material. I think that could be the problem, because self shadowing is only supported if you use custom shadow mapping.


No, the entire map is one big mesh. You think I should just seperate the mesh into the ground level (for mapping) and the houses/objects as a second layer and load them as seperate meshes?

That might be the issue, I wasn't aware meshes couldn't cast shadows on themself using the default engine parameters :shock: On the other hand just using a flat ground mesh instead of an all-in-one would probably make the Grid generation algorithm MUCH simpler, on top of things.

lilljohan

28-07-2008 19:11:06


Are the houses seperate meshes? If not, disabled CastShadows on them, set receive_shadows to on in the material. I think that could be the problem, because self shadowing is only supported if you use custom shadow mapping.


No, the entire map is one big mesh. You think I should just seperate the mesh into the ground level (for mapping) and the houses/objects as a second layer and load them as seperate meshes?

That might be the issue, I wasn't aware meshes couldn't cast shadows on themself using the default engine parameters :shock: On the other hand just using a flat ground mesh instead of an all-in-one would probably make the Grid generation algorithm MUCH simpler, on top of things.

I think you should do that. But try disabling shadows for it first to see if it works at all =)

Mephs

29-07-2008 02:19:10

Well I tried your suggestion, using a 2nd mesh to cast a shadow somewhere on my map, with no luck.

Then I tried something else. I have a single point light in the northeast of the map (raised to about 100 y), with ambience at full 0.



What could this mean?


private void CreateScene()
{
scene = mRoot.CreateSceneManager(SceneType.ST_GENERIC);
scene.AmbientLight = new ColourValue(0, 0, 0);
scene.ShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED;
pvCam = new PivotCamera(scene, 60, 150);
pvCam.SetTetherLength(90);
pvCam.SetTetherAngle(45);
pvCam.SetRotateAngle(45);
pvCam.SetTiltLimit(40, 50);
mWindow.AddViewport(pvCam.GetCamera());
pvCam.SetVisibility(0);

mRoot.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);
SceneNode node = scene.RootSceneNode.CreateChildSceneNode();
Entity ent = scene.CreateEntity("GroundTile", "Tile.mesh");
ent.CastShadows = true;
node.AttachObject(ent);

//Light
Light light = scene.CreateLight("test");
light.Type = Light.LightTypes.LT_DIRECTIONAL;
light.SetDiffuseColour(1, 0, 1);
light.SetSpecularColour(1, 0, 1);
light.Direction = new Vector3(1,-1,1);
light.CastShadows = true;

light = scene.CreateLight("newtest");
light.Type = Light.LightTypes.LT_POINT;
light.SetPosition(60, 120, -100);
light.SetDiffuseColour(1, 1, 1);
light.SetSpecularColour(1, 1, 0);
light.Direction = new Vector3(1, 1, -1);
light.CastShadows = true;



// Create SpriteManager
sprites = new SpriteManager(scene);

// Create initial sprites
Sprite spr = new Sprite("Knight2", new Vector3(3 + (6 * 4), 6, 3 - (6 * 5)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim2", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.SouthWest);
sprites.add(spr);
spr = new Sprite("Knight1", new Vector3(3 + (6 * 3), 6, 3 - (6 * 5)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim1", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.NorthEast);
sprites.add(spr);
sprites.ShowAll();
pvCam.SetVisibility(1);
}

Mephs

29-07-2008 03:04:50

With a little hacking around I got a glimpse of something! Huzzah!

Unfortunately it looks awful... and it's the only thing that's worked so far.

With the meshes split up (just the ground layer and the houses/trees/everything else)



Here it looks like I kinda got it to work, I had to use scene.ShadowTechnique = ShadowTechnique.SHADOWDETAILTYPE_TEXTURE;

This was the only setting that produced anything remotely usable, none of the other options even did anything, or they just completely blacked the screen out.

With the setting that works:



Note where the shading is from the houses in this corner.

When I turn the camera slightly the shading shifts off out of view



Here's the revised code:

scene = mRoot.CreateSceneManager(SceneType.ST_EXTERIOR_CLOSE);
scene.AmbientLight = new ColourValue(1f, 1f, 1f);
scene.ShadowTechnique = ShadowTechnique.SHADOWDETAILTYPE_TEXTURE;
pvCam = new PivotCamera(scene, 60, 150);
pvCam.SetTetherLength(90);
pvCam.SetTetherAngle(45);
pvCam.SetRotateAngle(45);
pvCam.SetTiltLimit(40, 50);
mWindow.AddViewport(pvCam.GetCamera());
pvCam.SetVisibility(0);

mRoot.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);
SceneNode node = scene.RootSceneNode.CreateChildSceneNode();
Entity ent = scene.CreateEntity("Map01_Ground", "Map01_Ground.mesh");
ent.CastShadows = false;
node.AttachObject(ent);
ent = scene.CreateEntity("Map01_Objects", "Map01_Objects.mesh");
node.AttachObject(ent);
ent.CastShadows = true;

//Light
Light light = scene.CreateLight("newtest");
light.Type = Light.LightTypes.LT_POINT;
light.SetPosition(30, 50, -50);
light.SetDiffuseColour(1, 1, 1);
light.SetSpecularColour(1, 1, 1);
light.CastShadows = true;




// Create SpriteManager
sprites = new SpriteManager(scene);

// Create initial sprites
Sprite spr = new Sprite("Knight2", new Vector3(3 + (6 * 4), 6, 3 - (6 * 5)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim2", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.SouthWest);
sprites.add(spr);
spr = new Sprite("Knight1", new Vector3(3 + (6 * 3), 6, 3 - (6 * 5)), 5f, 7.5f);
spr.AttachAnimation(new Anim("KnightAnim1", "KnightBB", 5, 3, Anim.Type.OSCILLATING, 1, 5, 8));
spr.SetFacing(Sprite.Facing.NorthEast);
sprites.add(spr);
sprites.ShowAll();
pvCam.SetVisibility(1);

lilljohan

29-07-2008 09:42:42

This is weird :)

SHADOWDETAILTYPE_TEXTURE, is not meant to be used directly however. I believe you got bitmask it with either DETAILTYPE_MODULATIVE or ADDITIVE, but that should be the same as using them TEXTURE_MODULATIVE or ADDITIVE directly.

http://www.ogre3d.org/docs/api/html/nam ... l#a531a128

Generally point lights = stencil shadows and spot, directional light = texture shadows =) And if your materials are not setup for additive lighting (ambient pass, (n lights) lighting pass, diffuse pass) then modulative should be used.

Btw, shadows can be a real pain in the ass :p Struggling with them myself at the moment.

Are your shadow casting lights going to be dynamic, if not then maybe you could use a pre rendered light map and some simple shadow blobs for the characters?

Mephs

29-07-2008 16:55:16

This is weird :)

SHADOWDETAILTYPE_TEXTURE, is not meant to be used directly however. I believe you got bitmask it with either DETAILTYPE_MODULATIVE or ADDITIVE, but that should be the same as using them TEXTURE_MODULATIVE or ADDITIVE directly.

http://www.ogre3d.org/docs/api/html/nam ... l#a531a128

Generally point lights = stencil shadows and spot, directional light = texture shadows =) And if your materials are not setup for additive lighting (ambient pass, (n lights) lighting pass, diffuse pass) then modulative should be used.

Btw, shadows can be a real pain in the ass :p Struggling with them myself at the moment.

Are your shadow casting lights going to be dynamic, if not then maybe you could use a pre rendered light map and some simple shadow blobs for the characters?


Shadow blobs for the characters would be fine. Right now I've kind of gotten back to focusing on the actual game mechanics than the visuals. Struggling with RayQueries ATM. Once I complete the Grid mapping classes, I can develop a shadow blob system for the sprites to use that grid or something. Or just make it a secondary billboard of each Sprite (each sprite is it's own billboardset). Would simplify that a lot, and I don't think I need shadows to be overly complicated, as the maps themselves aren't ever going to be excessively large.

I do however want to get some very nice fog/bloom effects in the end result to kind of liven up the scenery and make it more "dark ages" looking than what it looks like now.

Kerion

29-07-2008 17:08:44

You really should just generate a lightmap. Doing dynamic shadows for buildings that don't move is a HUGE performance hit. If you're worried about time of day issues, just do what I do: Generate one lightmap for every hour of the day and interpolate between them in a shader. It's not perfect transition, but the player will never notice, and it looks good.

Mephs

29-07-2008 17:24:00

You really should just generate a lightmap. Doing dynamic shadows for buildings that don't move is a HUGE performance hit. If you're worried about time of day issues, just do what I do: Generate one lightmap for every hour of the day and interpolate between them in a shader. It's not perfect transition, but the player will never notice, and it looks good.

Nah, time of day isn't dynamic. Basically the only actual active maps will either be A) indoors, or B) combat maps, meaning the time of day is determined at map generation.

I guess I can do that instead...how would I use a lightmap like that though? Excuse me but I'm totally new to all this 3d graphics stuff, still trying to determine the difference between a Specularphone, a Diffusamabob and an Antisopticalagon. (in other words I have no clear idea what I'm doing on the visual side just yet, I just write logic :P)

Kerion

29-07-2008 17:30:43

A lightmap is a texture that you render across the map. Look up lightmaps on google.

If you search on the main OGRE forums, you should find some example of lightmaps in OGRE.

It's a two step process:

Generate the lightmap
Render the scene using the lightmap

For a game like Quake that does a lot of radiosity testing for it's lightmaps, you do the lightmap creation as a level generation step, not at runtime. Some lightmap generation is fast enough to do at runtime, but even in my game engine, I generate the 24 per-day lightmaps when the user saves a map (they are stored as part of my map "package").

Mephs

29-07-2008 17:38:22

A lightmap is a texture that you render across the map. Look up lightmaps on google.

If you search on the main OGRE forums, you should find some example of lightmaps in OGRE.

It's a two step process:

Generate the lightmap
Render the scene using the lightmap

For a game like Quake that does a lot of radiosity testing for it's lightmaps, you do the lightmap creation as a level generation step, not at runtime. Some lightmap generation is fast enough to do at runtime, but even in my game engine, I generate the 24 per-day lightmaps when the user saves a map (they are stored as part of my map "package").


I used to use Quake editors when I was a kid, to generate some maps so I *kind* of know a bit about using Lights in that, if it's any bit the same. Since my maps aren't huge and are just simple meshes I suppose that may make lightmapping them easier?

What is it just placing lights around the map? Eventually I want to be able to integrate the lightmapping as part of an editor people can use to set light positioning and whatnot. Basically what I'm doing in the long run is having the maps designed in a 3d modelling program, then you can import the map as a mesh and map Tilespaces to it as a grid (where units can move, and assign properties to each tile, like ground types, sand, water, foilage, grass, etc.)

The height is just going to be determined using Newton physics and RaysceneQueries to give the tile it's height properties (for things like height advantage against a target unit, or generating Paths for the units as well).

I'll check out tutorials or whatever on light mapping though, thanks for a point in the right direction

Kerion

29-07-2008 17:46:27

You can generate the lightmaps to take in to account multiple light sources, if that's your question. Remember, there is a difference between a dynamic light (Ogre::Light), and a static one (something that exists in your editor, but not the actual game world). You would use static lights to build your light map, while dynamic lights (such as, a flickering torch) would be something that happens at runtime and is in addition to your static lightmap, not a replacement for.

Mephs

29-07-2008 17:48:32

You can generate the lightmaps to take in to account multiple light sources, if that's your question. Remember, there is a difference between a dynamic light (Ogre::Light), and a static one (something that exists in your editor, but not the actual game world). You would use static lights to build your light map, while dynamic lights (such as, a flickering torch) would be something that happens at runtime and is in addition to your static lightmap, not a replacement for.

Ah, I see what you're getting at. So the lightmap is generated in say, 3DS or Blender, but then if I want to use bloom and other effects to take advantage of that lighting (like say light coming from a window that has that bloom glow to it) would they need to be dynamic and generated at runtime then?

The only thing I need the lighting for is to generate shadows from the model.

Kerion

29-07-2008 18:55:23

You can generate the lightmaps to take in to account multiple light sources, if that's your question. Remember, there is a difference between a dynamic light (Ogre::Light), and a static one (something that exists in your editor, but not the actual game world). You would use static lights to build your light map, while dynamic lights (such as, a flickering torch) would be something that happens at runtime and is in addition to your static lightmap, not a replacement for.

Ah, I see what you're getting at. So the lightmap is generated in say, 3DS or Blender, but then if I want to use bloom and other effects to take advantage of that lighting (like say light coming from a window that has that bloom glow to it) would they need to be dynamic and generated at runtime then?

The only thing I need the lighting for is to generate shadows from the model.


Yes, lightmaps generate the light/dark areas for your static map objects, such as your houses. If you want your characters to cast shadows, that is when you using dynamic shadowing.

So, for instance, lets assume you only have one static light (the sun):

You would generate a lightmap using that position, then in your game world, you would use a directional light coming from the same direction, but only have your characters be shadow casting objects. In this way, your static objects have nice lighting and shadows from the sun, but only your characters cast dynamic shadows.

In this scenario, you would draw your static game world with lighting OFF in the material, because your "lighting" is provided by a static lightmap. Your characters would draw with lighting and shadows ON, so that their lighting updated as they moved.

Mephs

29-07-2008 19:10:56

Alright cool, guess I gotta pick up Blender then. That'll work. I guess you just make seperate lightmaps for each time of day configuration (there'd probably only be 3, broad daylight, dusk, and night. I guess I just save those as seperate meshes or something?

Also, was mostly curious about how to implement effects like bloom lighting (don't care about special shadows as a result of it) on things like night-time lit windows and other lights about the map, would those have to be dynamic lights created at runtime or can that effect be done as part of the light mapping?

Kerion

29-07-2008 19:35:28

First off, lightmaps aren't meshes, they are textures, that are drawn as a pass in your technique. Again, search the main OGRE forums for how to apply lightmaps. Generally you won't have one for each object, you'll have a big lightmap that is stretched across your entire level.

Second, bloom is an after effect that you would apply using a compositor. If you mean glow, that would be something you do in the material for the window on the build.