Shadow disapeared on Instanced Objects away from camera

I understand that Instanced Node’s objects will cull out if it’s not in camera direction, but why the shadow, though, and how can I fix this?





Hi,

I think one trick could be to check against an enlarged bound of geometry (e.g. doubled or tripled bound) when we check for camera frustum intersects so those instances that are slightly outside from the camera view will still be rendered for sake of shadow.

I do not know how shadow works but I know all instances of instanced geometry are still sitting inside the scene graph but they are culled so they won’t be rendered. Probably shadow renderer can somehow use that to decide where to put the shadow. Not sure though!

1 Like

Thank you for your response
I’ll try your suggestion and I’ll response back to you

1 Like

It worked
But doesn’t that make an issue with BoundingBox’s methods?

Not sure but I think you should not modify the original geometry bound instead we should change the InstancedGeometry class to internally do this by cloning the original bound and scaling the clone instead. Though not sure what scale rate we should use. Probably doubling the bond would be fine.

@pspeed any thoughts?

1 Like

I think to make it on the users preference to set the variable they want!

1 Like

I mean, probably this is not really fixing the issue but just hacking around it for this particular scene.

I’m not very familiar with the shadow code nor the instancing code… but something between the two is unhappy. If all of these buildings are instances of the same geometry and bundled into a single mesh (by JME) then if it’s doing any building-specific culling at all (versus culling the whole batch) then the instance stuff must be doing its own frustum magic and probably not taking shadow frustums into account.

And for what it is worth I provided a prototype implementation of the “hack” in my fork: :slightly_smiling_face:

It introduces an instance culling function that can be switched out.

Edit:

Note that the function is a static class variable so must be set class-wide:

InstancedGeometry.setInstanceCullingFunction()

Edit2:
If this is beneficial to the engine I can submit a PR

Yeah, so based on Ali’s change…

I was right about the magic. It’s not very smart magic which is kind of the down side of having such magic in the first place. An unfortunate side effect of the way JME does frustum culling separately for shadows.

So I guess with the above change that a user wanting proper shadows would have to implement a function that took shadow light frustums into account before culling?

Yes, I believe so, for a proper shadow. But I do not know how shadow works so I have no idea how to implement that.

As you can see in my default implementation I use the bound-scale hack to workaround shadow issues. But maybe I should take that hack out from the default implementation and just do the bare-bone cam frustum checking like before.

A bound scale hack will only work in scenes where the camera is relatively close to the thing casting the shadows.

My understanding is that for shadows, the scene is rendered again from the perspective of the light. This will obviously have its own frustum which the instanced geometry magic is ignoring. (I’d argue that this magic should not even exist because of this and maybe half-a-dozen similar issues it will cause… better that the user break up their scene spatially but now it’s there and so we must live with it.)

But if the magic is going to be there, the “right” solution is to have it pay attention to the frustums of whatever shadow-casting lights are around… and only the user can know that, I guess.

1 Like

Well, …hmm…, I think not necessarily close to the camera position but close to camera frustum I believe.

Yes, but I think what is considered “close to the frustum” will vary a lot by how far that thing is from the camera. “close” seems subjective.

Also the angle of the light will matter a lot, too. Low light angles will cast long shadows.

1 Like

So a noob question
Do I have to extend or Make my own InstancedGeometry to implement your method now?
I work with Release version, do I have to download the source version to work?

Yeah, right. In which case, my hack will suck.

I guess only useful when it is noon time :wink:

Well yes, you need to build it from the source If you want to give it a try.

1 Like

I modified it and removed the hack and submitted a PR. The default implementation is checking against camera frustum like before and does not care about shadow but if someone wants proper shadow they can now just unset the function and this will disable instance culling and will resolve the shadow issue or as pspeed said they can implement a proper function that took shadow light frustums into account.

Is this fine?

5 Likes

Seems fine to me.

…and yeah, I suspect for most folks who have an issue with the magic, being able to null out the magic is probably their best/easiest solution. Anyone really concerned about not having to break up their scene better can implement a proper version. Win, win, win all around.

2 Likes

Thanks for the review.

@carpenter

The PR is merged into the main repo. You can build the engine from the master branch and add the below code to disable instance culling. It should resolve the shadow issue you described.

InstancedGeometry.setInstanceCullingFunction(null);

Or you can implement your own instance culling function.

Edit:

Instruction to build engine

2 Likes