Dynamic terrain shadows?

Hello everyone

I just began using jmonkeyengine and went to the point of making a terrain out of an heightmap

I tried then to implement shadows on it, i used pssm and basic shadows but with both of them, the result looks ugly and buggy.

How do i implement good dynamic shadows on a heightmap based terrain ?

Thanks in advance

do you have a screenshot of the issues you are seeing? ‘Ugly and buggy’ isn’t very helpful to determine what is happening.

http://i.imgur.com/NXfis.jpg

i don’t know why it does that

you may want to activate PCF filtering for shadow edges

try

[java]

pssmRenderer.setFilterMode(FilterMode.PCF4);

[/java]

for example

thanks, it’s a bit better now

I think it also comes because of the fact that the terrain is not smooth, it looks like a polygon

is there a way to smooth the terrain and make it more “round” ?

You can smooth an AbstractHeightMap using the smooth method.

1 Like

Hey, I thought you guys could use the code. I took only the part that could be of interest. I’m working with Stracker on this project and solving this shadow issue is for now our number 1 occupation.



[java] pssm = new PssmShadowRenderer(assetManager, 4096, 3);

pssm.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());

pssm.setFilterMode(FilterMode.PCF4);

viewPort.addProcessor(pssm);



}

private void initTerrain() {



mat_terrain = new Material(assetManager,

“Common/MatDefs/Terrain/Terrain.j3md”);



/** 1.1) Add ALPHA map (for red-blue-green coded splat textures) /

mat_terrain.setTexture(“Alpha”, assetManager.loadTexture(

“Textures/alphamap.png”));



Texture sand = assetManager.loadTexture(

“Textures/sand.png”);

sand.setWrap(WrapMode.Repeat);

mat_terrain.setTexture(“Tex1”, sand);

mat_terrain.setFloat(“Tex1Scale”, 64f);





/
* 2. Create the height map /



Texture heightMapImage = assetManager.loadTexture(“Textures/height.png”);



ImageBasedHeightMap heightmap = new ImageBasedHeightMap(ImageToAwt.convert(heightMapImage.getImage(), false, true, 0), 1f);

heightmap.smooth(2f);

heightmap.load();



/
* 3. We have prepared material and heightmap.

  • Now we create the actual terrain:
  • 3.1) Create a TerrainQuad and name it "my terrain".
  • 3.2) A good value for terrain tiles is 64x64 – so we supply 64+1=65.
  • 3.3) We prepared a heightmap of size 512x512 – so we supply 512+1=513.
  • 3.4) As LOD step scale we supply Vector3f(1,1,1).
  • 3.5) We supply the prepared heightmap itself.

    /

    int patchSize = 65;

    terrain = new TerrainQuad(“my terrain”, patchSize, 1025, heightmap.getHeightMap());



    /
    * 4. We give the terrain its material, position & scale it, and attach it. /

    terrain.setMaterial(mat_terrain);

    terrain.setLocalTranslation(0, -100, 0);

    terrain.setLocalScale(2f, 1f, 2f);

    terrain.scale(0.25f, 0.25f, 0.25f);

    rootNode.attachChild(terrain);



    /
    * 5. The LOD (level of detail) depends on were the camera is: */

    TerrainLodControl control = new TerrainLodControl(terrain, getCamera());

    terrain.addControl(control);



    Spatial zecactus = assetManager.loadModel(“Models/cactus.mesh.xml”);

    zecactus.scale(1f, 1f, 1f);

    zecactus.rotate(0.0f, -20.0f, 0.0f);

    zecactus.setLocalTranslation(0.0f, -73.0f, -2.0f);

    rootNode.attachChild(zecactus);



    DirectionalLight sun1 = new DirectionalLight();

    sun1.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));

    rootNode.addLight(sun1);



    rootNode.setShadowMode(ShadowMode.Receive);

    terrain.setShadowMode(ShadowMode.CastAndReceive);

    zecactus.setShadowMode(ShadowMode.Cast);

    [/java]



    For now, it just looks like a desert with a cactus (object zecactus) and some buggy shadows. We think there aren’t enough polygons for the terrain to render nice shadows.

Does this not also render a 4096 Shadow Map for the cactus? Seems very inefficient. Is it possible to render such a sized map only for the terrain itself and a 512 for meshes?

This was over two years ago if you didn’t notice :wink:

i did. But im wondering if there is another way now, to create good shadows for the terrain?

Severall, if its static just generate a lightmap outside jme, that kinda beats most other solutions.
If not you can use the dynamic shadow approach, or do raytraces to recalculate the affected parts of the lightmap.

The terrain is randomly generated so im not sure if i can make a lightmap from the generated heightmap.

@TastyLemons said: Does this not also render a 4096 Shadow Map for the cactus? Seems very inefficient. Is it possible to render such a sized map only for the terrain itself and a 512 for meshes?

Interesting question…

If you can choose the node the shadowCam uses as it’s root (or geometry list based off of the light and what it effects), then you should be able to by dividing up your scene graph (terrain in it’s own Node attached to rootNode, other geoms attached to a secondary branch). I can’t remember off the top of my head if the geometry list the shadowCam renders is based off of the light or not (for whichever shadow renderer). If it isn’t, it probably should be updated to do this, as it would make it a whole lot easier to implement prioritized shadow mapping.

@nehon could answer this, as he wrote them all.

EDIT: Also keep in mind, the 4096 map is for all geometries that cast shadows, not just the cactus alone.

1 Like

Yeah in that case there are 3x4096 shadow maps, which is IMO overkill.
The directionalLightShadowRenderer formerly known as PssmShadowRenderer uses the PSSM technique.
I invite you too document on this technique for complete information, but let’s say it’s splits the camera frustum in several areas (here 3) and render a shadow map for each area. The splits are not regular, the closest the split the smaller it is. As a result you have more detailed shadows near the camera and details decrease as the distance to the camera increase.

@t0neg0d not sure what the question is, but the shadow renderers use shadow queues (build from objects marked as cast/receive shadows), then only the geometries in the light’s area of influence are rendered. For directional light, only the objects in the splits are rendered.It doesn’t use the rootNode either, just what was populated in the shadow queues.
Right now you can’t choose what geom is endered with what shadow renderer (if you have several).

1 Like
@nehon said: Yeah in that case there are 3x4096 shadow maps, which is IMO overkill. The directionalLightShadowRenderer formerly known as PssmShadowRenderer uses the PSSM technique. I invite you too document on this technique for complete information, but let's say it's splits the camera frustum in several areas (here 3) and render a shadow map for each area. The splits are not regular, the closest the split the smaller it is. As a result you have more detailed shadows near the camera and details decrease as the distance to the camera increase.

@t0neg0d not sure what the question is, but the shadow renderers use shadow queues (build from objects marked as cast/receive shadows), then only the geometries in the light’s area of influence are rendered. For directional light, only the objects in the splits are rendered.It doesn’t use the rootNode either, just what was populated in the shadow queues.
Right now you can’t choose what geom is endered with what shadow renderer (if you have several).

Ok… that answered it… thanks!

The thought was, to limit the geometry list based on what geometries the light effects (maybe this happens already)… but since lights are attached to Nodes and only apply to the geometries contained in that node (children included), the question above made me wonder if that is taken into account for shadow mapping (since the shadow renderer needs a light to base it’s perspective from)

It would go a long ways towards minimizing impact of the shadow renderers if the geometry list matched that of the light (compared to the shadow queues of course)

@t0neg0d said: It would go a long ways towards minimizing impact of the shadow renderers if the geometry list matched that of the light (compared to the shadow queues of course)
I don't think so, because there is already a light frustum culling, so we don't render geometries outside of the light area. basically we pick in the shadow queues the geometries affected by the current light.
@nehon said: I don't think so, because there is already a light frustum culling, so we don't render geometries outside of the light area. basically we pick in the shadow queues the geometries affected by the current light.

Not sure how that would work for directional light since it goes and goes and goes. And seeing as a directional light can be attached to a nested child node, the geometry list for shadows would be > than the list of affected geometries.

It’s not that big of a deal… but it would be super sweet if distant geoms could be rendered with an ultra low res shadow map and closer could be rendered with a hi res map. This would make a pretty significant difference for scene cams with a huge far clipping plain and a sun light directional shadow renderer.

Thus the comment about prioritized shadow mapping.

@t0neg0d said: Not sure how that would work for directional light since it goes and goes and goes. And seeing as a directional light can be attached to a nested child node, the geometry list for shadows would be > than the list of affected geometries.
True, actually, in that case shadows would be rendered for objects that are not affected by the light. Anyway, there are plan to completely remove this light behavior (lighting only the geoms in the sub node). it's known as issue 510, and it's about having lights that only render what's really in their area of influence. https://code.google.com/p/jmonkeyengine/issues/detail?id=510&q=label%3AProduct-jME3&colspec=ID%20Type%20Status%20Component%20Priority%20Difficulty%20Product%20Milestone%20Owner%20Summary
@t0neg0d said: It's not that big of a deal... but it would be super sweet if distant geoms could be rendered with an ultra low res shadow map and closer could be rendered with a hi res map. This would make a pretty significant difference for scene cams with a huge far clipping plain and a sun light directional shadow renderer.
That could be done actually...idk how it would play at the split seams, but that's easy enough to test...
@nehon said: True, actually, in that case shadows would be rendered for objects that are not affected by the light. Anyway, there are plan to completely remove this light behavior (lighting only the geoms in the sub node). it's known as issue 510, and it's about having lights that only render what's really in their area of influence. https://code.google.com/p/jmonkeyengine/issues/detail?id=510&q=label%3AProduct-jME3&colspec=ID%20Type%20Status%20Component%20Priority%20Difficulty%20Product%20Milestone%20Owner%20Summary

That could be done actually…idk how it would play at the split seams, but that’s easy enough to test…

It would potentially have negative impacts in other ways just trying to manage your scene in this fashion, but… if the lighting is changed as described it would be much easier… however, will it still be possible to limit what a directional light effects?

Nope.
But I guess we could introduce some light buckets of some sort…idk.
I never have the use of partitioning my lights in scenes. I know some use this because there are many lights in the scene and it’s killing perf to attach every light to the root node, but this system would be here to prevent this kind of situation. let’s say you have a point light of 1 WU radius only the geom in this radius would be rendered, even if the light is attached to the root node. that makes partitioning a lot less useful.