Proposal to integrate Shadow Mapping

Hmm, this is something subtle indeed. Are you sure you’re loading a bam file that you’ve written since your change? If you comment out the additional code in fillin() and write_datagram() (and write a new bam file), does it work correctly?

David

Still crashes. Maybe Spotlight’s CycleData stuff is interfering? Then again I have no idea what that does.

This seems to work:

void LightLensNode::
write_datagram(BamWriter *manager, Datagram &dg) {
  //PandaNode::write_datagram(manager, dg);
  Light::write_datagram(manager, dg);
}
void LightLensNode::
fillin(DatagramIterator &scan, BamReader *manager) {
  //PandaNode::fillin(scan, manager);
  Light::fillin(scan, manager);
}

But if I comment out the lines with PandaNode, I get the crash. :S
This also happens when none of the lights in the bam have shadows enabled.
Any clues?

Am I reading this right to imply that you can have lights specified in bam files? And would that imply that you can have lights in egg files? I would rather like to add such a capability to Chicken…

Yeah, you can already write lights to .bam files. Writing them to .egg will be my next goal. :slight_smile:

since you’re up to, how 'bout to include the camera as well? wait a moment: am I wrong or you guys are thinking to make load big scenegraph files (and maybe dump’em) by the panda?

Perhaps you can forward me the relevant changes so I can try to reproduce the crash?

David

Sure. Should I commit these particular changes to the light inheritance stuff or should I e-mail them?

I guess there’s no harm in committing them–it only crashes when you actually try to save lights to a bam file, right? So, go ahead and do that.

David

Done. I just checked in the light changes, not yet the GSG/RS/SG changes.

To reproduce, take the Disco Lights sample, add a render.writeBamFile just before the run() call, and pview it.

Maybe you missed a file?

camera.cxx: In constructor ‘Camera::Camera(const std::string&, Lens*)’:
camera.cxx:32: error: no matching function for call to ‘LensNode::LensNode(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, Lens*&)’
lensNode.h:36: note: candidates are: LensNode::LensNode(const LensNode&)
lensNode.h:33: note:                 LensNode::LensNode(const std::string&)

David

Oh. Well, that’s stupid of me - I even triple checked that I had all files.
My apologies. Try now.

Noticed your commits. Works awesomely now, thanks alot!

Yay, shadows in pview:
pro-rsoft.com/screens/pview-shadows.png

I totally forgot about the “GL texture creation failed” issue. It’s not a critical issue, it just spawns an annoying error on the console.

The problem is at line 400 of glShaderContext_src.cxx:

    if (!gsg->update_texture(tc, false)) {

In that update_texture function, it fails - apparently because the texture hasn’t been rendered into yet, even though it is supposed to contain data (I used make_ram_image, remember).
So I think we can at least work around it by not passing a texture to the shader (or an empty one) when it hasn’t been loaded / rendered into yet.
Is there a way we can detect that? Or do you have a better idea?
I’ve tried a tex->is_prepared but this seems to return true nevertheless.

Hmm. Once again, it will probably be easier for me to help diagnose this when I can reproduce the problem myself. Does this require additional code you haven’t yet committed?

David

Yeah, I’ll pretty much need to commit the rest of the stuff.

For some reason, I just did a semi-clean build of the cvs head after committing my stuff there. I can’t seem to reproduce the warning message anymore - maybe it’s a recent commit that fixed it, or it was related to the now-resolved circular dependency issues.

So I guess we don’t need to worry about that anymore. :slight_smile:
Basically everything is functional now and on CVS. Thanks so much for helping me through the process of developing shadows!

fantastic pro_r I guess the upcoming release shall open a new era for P3D
PS: would be great to have that disco tutorial with shadows in the samples tree

Just checked in a fix improving the performance by 50% (by disabling color write for the shadow camera) and I’ve also found a fix for the graphical artifacts (the push bias is no longer needed).

There are still artifacts that are visible on infinitely-thin objects, though. The best way I’ve found to fix them was by applying an offset into the depth buffer. Since modeling programs like Blender support depth offsets, it will be easy for artists to fix shadow artifacts on thin objects.

So, long story short: would you mind if I added depth-offset to the Egg syntax? It would simply wrap around a DepthOffsetAttrib.
I’d also add a nodePath.setDepthOffset method. People can easily use that for creating decals like bullet holes.

I’m also planning to add support for point lights in the future, and transparent+colored shadows (e.g. if light shines through a stained-glass window).
David, what do you think the best way to implement the point lights thing would be? Would non-linear lenses like FisheyeLens be useful? If not, would I create a CubeMapCamera class (where PointLight will inherit from) that simply wraps around six cameras?

The depth-offset additions seem like fine, useful features.

I don’t think a FisheyeLens will be useful here, since you’re talking about using the hardware to render six different images for a point light, right? The FisheyeLens doesn’t have much to do with that implementation detail.

I’m not sure how a CubemapCamera class would work, though. Right now, we implement a cubemap camera by actually taking six different Camera nodes and parenting them to a common node. Should we create a new concept of a Cubemap camera that contains six cameras embedded within one node? Or maybe, just one Camera object with six different lenses facing in different directions? (With the recent code, a Camera can now contain multiple lenses; and each lens can be aimed differently.)

However, either of these approaches does cause problems in the cull traverser, which is designed along the assumption that any one Camera object requires only one cull pass to accumulate its visible geometry, no matter how many times the Camera appears within the frame. This is a very useful optimization, particularly for multipass and stereo effects; but the six different cameras of a cubemap view will each require their own cull traversal (because they are looking in completely different directions).

David