How to go about casting shadows on point sprite billboard-like objects?

Hi,

I have implemented/adapted a billboarding shader a couple weeks ago that would take point sprites as input and its vertex shader would displace its position based on the desired object size. It looks like this:

[java]
// ---------- Billboarding effect ----------
if(inSize > 0){
// Convert vertex location to world-view space, ie: camera-relative space
pos = g_WorldViewMatrix * pos;

    // Figure out how to offset it in camera space
    float offset = texCoord.x - 0.5;  // (make it -0.5 to 0.5)
    pos.x += offset * inSize;
}
// -----------------------------------------

if(inSize > 0){
    gl_Position = g_ProjectionMatrix * pos;
}
else{
    gl_Position = g_WorldViewProjectionMatrix * pos;
}

[/java]

So, when the vertex shader sees an inSize parameter, it displaces its vertex position so that it ends up being a vertical quad. You get the point. It enables very fast rendering of thousands of objects.

Now, the problem is that since this is initially just a point (and not a quad) JME3 does not cast its shadow (or does, but it’s infinitely small and thus invisible). Is there a way to achieve this? I was thinking about maybe like doubling all those point sprites with a real quad copy, front and back culled or something, just so that its correct shadow is casted but leaving the quad invisible. So like only render it in the shadow pass… not even sure this makes sense. Any ideas?

Thx :smiley:

Actually the shadow renderer does use a normal rendering, you might need to adjust /manipulate the used material from it tho.

there are 2 steps in shadow rendering :

  • generating the shadow map (render the depth of the scene from the light point of view)
  • Apply the shadows on the rendered scene.

Both passes uses a material with a vertex and frag shader.
If your material displaces the vertices in the vert shader, the vertices needs to be displaced as well in the vert shader of those 2 passes.

To do so, your material must have a preshadow technique that has a vert shader that displace the vertices (i recommend using the ShadowFilter in this case because it will save you from doing this also for the post shadow pass)

look at how the preshadow technique is done in the lighting material and look at the preshadow.vert.

1 Like

Hi Eric,

I’m using the shadow FILTER (not renderer) if it makes more sense. I could go back to the shadow RENDERER if it’s going to output good fps, but I found that it delivered slightly better performance in my scenario to use the shadow FILTER instead. I’ve read the FILTER performance curve surpasses the RENDERER around >20 shadow receiving objects. Let me know what you guys think if I need to go back to the RENDERER for this to work…

Hi Rémy,

@nehon said: To do so, your material must have a preshadow technique that has a vert shader that displace the vertices (i recommend using the ShadowFilter in this case because it will save you from doing this also for the post shadow pass)

This is extremely valuable information to me. Thank you, I’ll look into it. That sounds exactly like what I’m after. At the moment I was n00bly duplicating the thousand objects, rotating them towards the sun on XZ planes, GeometryBatching them and FrontAndBack-culling them so that the only thing that is displayed is their shadows which surprisingly works flawlessly and gives extremely good fps (it literally draws 2fps out of nearly 70fps) when I create this shadow-making object layer. It’s like an impostor but for shadows only.

I’ll now look into adapting the real objects’ material pre-shadow technique so that it effectively displaces its vertices just like it does in the rendering pass and I’ll post some results here. I haven’t seen anybody talking about this in the JME3 forums yet.

Thanks :smiley:

Alright, +1 to Rémy for this valuable information… I have implemented the same expanding point GLSL code in the preShadow technique as in the billboard shader itself and now my billboards are casting shadows just like any other full vertices models. The only thing I’m wondering is this:

Since the billboards will face the sun in the PreShadow pass and face the camera on the render pass, then most of the time the 2 will cross in a X shape. So inevitably there will be half-ish of the tree in its own shadow and the other half in the sun. This self shadowing is not looking good at some time of the day (depending of where the sun is). Is there a way to prevent self shadowing? inb4 ShadowMode.Cast. Already tried this and it does not change anything.

That was another question I had: is there something to add in the material file or in the GLSL shader to behave using JME3’s ShadowMode hint? Setting it to “Off” removes effectively its shadow, but setting it to “Cast” does the same thing as “CastAndReceive” thus the billboard triggers self shadowing.

Am I correct to assume that this would not happen with a PostShadow or would it be the same? What can I do to overcome this issue? :-/

Thx!

If you are using the shadow filter instead of the shadow renderer then I believe everything receives shadows because it’s all done in post on the entire frame. So essentially everything is ‘receive’.

1 Like

Thanks Paul for this as it explains this strange behaviour. As a matter of fact, it’s obvious to me now that it’s an architecture problem. Billboards can’t possibly behave correctly with shadows since all shadows are casted in the same pass, so there is no difference between self shadow and another object’s shadow, it’s all just one big shadow. That causes some serious headaches. How will one go about avoiding self-shadowing on quad billboards. I’ve looked on Google for ideas and I’m stuck, so I might simply have to displace the preShadow pass vertices off enough so that it never touches the billboard shape that is used in the render pass.

That “works” but at the same time it sucks because the shadow is not “connected” at the billboard’s feet. Take a tree for example, the shadow will start like 1 meter away from the trunk/terrain intersection… not very realistic, but at least the top part of the tree will not look half self shadowed.

I do not think shadowing billboards is possible, really. Unless they are small and you shadow the whole thing… but that would be based on some voxel lighting or something, not real shadows.

You may have to rethink the use of billboards for things that are shadowed.