Shadow Mapping Not Working

I’d like to use the default shadow mapping.

Here’s how I’ve set up my lights:

// Setup the lights.
	window->set_lighting(true);

	// The first light simulates the sun.
	PT(PointLight) pLight01;
	pLight01 = new PointLight("pLight01");
	pLight01->set_point(LPoint3f(0, 0, 50));
	pLight01->set_attenuation(LPoint3f(0, 0, 0.5));
	NodePath pLight01np = window->get_render().attach_new_node(pLight01);
	window->get_render().set_light(pLight01np);

	// The second light casts shadows.
	PT(DirectionalLight) dLight01;
	dLight01 = new DirectionalLight("dLight01");
	dLight01->set_color(LVecBase4f(0.8, 0.8, 0.5, 1));
	NodePath dlnp = window->get_render().attach_new_node(dLight01);
	dlnp.set_pos(0, 0, 50);
	dlnp.set_hpr(0, 0, 0);
	window->get_render().set_light(dlnp);

	// The third light creates ambient light in the scene.
	PT(AmbientLight) aLight01;
	aLight01 = new AmbientLight("aLight01");
	aLight01->set_color(LVecBase4f(0.2, 0.2, 0.2, 1));
	NodePath aLight01np = window->get_render().attach_new_node(aLight01);
	window->get_render().set_light(aLight01np);

	// Enable shadows.
	window->get_render().set_depth_offset(1);
	// Use a 512x512 resolution shadow map
	dLight01->set_shadow_caster(true, 512, 512);
	
	// Enable the shader generator for the receiving nodes
	window->get_render().set_shader_auto();

I’m using pandagl for rendering and I’m using an nVidia GeForce 7600 GS card (it’s a bit old but should be OK for this?).

Have I missed something here?

Yes, you should set up the frustum of the DirectionalLight correctly, before it can work with shadow mapping. show_frustum() may help you with that.

Okay, this is a bit of a hack…

Make a dummy spotlight, but don’t do anything with it.
For some reason, setting up a spotlight fixes the directional light shadows

PT(Spotlight) spot= new Spotlight("Spotlight 1");
NodePath spotnp=window->get_render().attach_new_node(spot);
window->get_render().set_light(spotnp);

I’ve managed to get shadow mapping working :smiley:

However, I can’t seem to change the directional light’s frustum. I’ve tried the following:

// The second light casts shadows.
	PT(DirectionalLight) dLight01;
	dLight01 = new DirectionalLight("dLight01");
	dLight01->set_color(LVecBase4f(0.8, 0.8, 0.5, 1));
	dLight01->show_frustum();
	dLight01->get_lens()->set_fov(75);
	dLight01->get_lens()->set_near_far(1.0, 60);
	NodePath dlnp = window->get_render().attach_new_node(dLight01);
	dlnp.set_pos(-20, -30, 50);
	dlnp.set_p(-90);
	window->get_render().set_light(dlnp);

set_near_far works properly however I can’t get the field of view of the light to change. What I’m getting at the moment is a rectangular column of light, but what I was is to spread it out over the whole scene.

How do I do this?

This’ll expand it.

dlight->get_lens()->set_film_size(50,50);

Note, don’t make it too large, or you’ll have to raise the resolution of the shadow, which’ll kill your fps.

You’re probably looking for a Spotlight. Spotlights are a lot easier to setup, and work much more easily with shadow mapping.

I’ve got a Spotlight casting shadows now - thanks for the help.

Hello,
i am having too trouble getting directional lights working as shadow casters (spotlights are working as expected). Here’s the code used to set up the scene:

    // Load model of Suzanne head
    NodePath node1 = window->load_model( framework->get_models(), "models/suzanne.bam" );
    node1.reparent_to( window->get_render() );

    // Load ground
    NodePath node2 = window->load_model( framework->get_models(), "models/ground.bam" );
    node2.reparent_to( window->get_render() );

    // Create light and attach
    DirectionalLight *directionalLight = new DirectionalLight( "Directional0" );
    directionalLight->set_color( Colorf( 0.8f, 0.8f, 0.8f, 1.0f ));
    directionalLight->set_shadow_caster( true, 1024, 1024 );
    directionalLight->get_lens()->set_film_size( 50, 50 );
    directionalLight->get_lens()->set_fov( 75.0f );
    directionalLight->show_frustum();
    NodePath d = window->get_render().attach_new_node( directionalLight );
    d.set_hpr( 45.0f, -45.0f, 0.0f );
    window->get_render().set_light( d );

    // Shadows
    window->get_render().set_shader_auto(); // Everything receives shadows

And this is the result:

Can someone please also explain me why the frustum of the directional light has a pyramidic shape? I thought that directional lights have no origin and are parallel, they just have a direction.

Thanks,
egrath

Why are you setting the FOV angle? A directional light has no field-of-view angle.

Hi,
because it was mentioned a few posts above :slight_smile: Thought that it has eventually some influence on the shadows even if it shouldn’t.
egrath

Hi,
got it working with the following code:

    // Create light and attach
    DirectionalLight *directionalLight = new DirectionalLight( "Directional0" );
    directionalLight->set_color( Colorf( 0.8f, 0.8f, 0.8f, 1.0f ));
    directionalLight->get_lens()->set_film_size( 50, 50 );
    directionalLight->get_lens()->set_near_far( -10.0f, 50.0f );
    directionalLight->set_shadow_caster( true, 2048, 2048 );
    directionalLight->show_frustum();
    NodePath d = window->get_render().attach_new_node( directionalLight );
    d.set_hpr( 45.0f, -45.0f, 0.0f );
    window->get_render().set_light( d );

    Spotlight *sp = new Spotlight("SP");
    sp->set_color( Colorf( 0.0f, 0.0f, 0.0f, 1.0f ));
    sp->set_shadow_caster( false );
    NodePath spn = window->get_render().attach_new_node( sp );
    window->get_render().set_light( spn );

In difference to the previous code i did the following:

  • Set near/far
  • Add a spotlight (no color, no shadow caster)

One question remains: Why is shadow generation only working when there’s a spotlight added - even if this spotlight does not cast shadows.

Thanks,
egrath

hi

i have a similar problem with the shadows. i uploaded a small video to rapishare to illustrate the problem.
http://rapidshare.com/files/420821456/panda3d_x264.avi.html
as you can see, the bottom cubes of the tank get shadowed wrong. any hint on how to solve the are appretiated.
i used the code one post above mine.