Shadow artifacts with directional light and alpha quad

Hi all,

I’m getting very bad shadow artifacts when using a directional light, as you can see in this screenshot.

So I have a sphere with a quad intersecting it. The quad has an alpha texture applied to it and is rendered in the transparent queuebucket. I’ve tried everything I could think of; changing blendmodes, edge filtering techniques, lambda values, etc… I even tried a custom obj for the quad with more triangles, but nothing seems to have an effect.

Here’s the relevant code:

For the rings (quad):

Quad quad = new Quad((float)planet.getRadius() * scale, (float)planet.getRadius() * scale);
	spatial = new Geometry(planet.getName() + "Rings", quad);
	spatial.setLocalTranslation(-(float)planet.getRadius() * scale/2f, -(float)planet.getRadius() * scale/2f, 0);
	spatial.setShadowMode(ShadowMode.CastAndReceive);
	
	Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
	mat.setBoolean("UseMaterialColors",true);
	mat.setColor("Ambient", ColorRGBA.White);
	mat.setColor("Diffuse", ColorRGBA.White);
	mat.setTexture("DiffuseMap", assetManager.loadTexture("assets/Textures/" + planet.getName() + "RingsColor.png"));
	mat.setTexture("AlphaMap", assetManager.loadTexture("assets/Textures/" + planet.getName() + "RingsAlpha.png"));
	mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
	mat.getAdditionalRenderState().setBlendMode(BlendMode.PremultAlpha);
	spatial.setMaterial(mat);
	
	spatial.setQueueBucket(Bucket.Transparent);
	planetNode.attachChild(spatial);

For the shadow and light:

sunlight = new DirectionalLight();
	sunlight.setColor(ColorRGBA.White.mult(0.85f));
	Vector3d v = spaceship.getPos().subtract(planetMap.get("Sun").getPos()).norm();
	sunlight.setDirection(v.toFloat());
	rootNode.addLight(sunlight);

FilterPostProcessor fpp = new FilterPostProcessor(assetManager);

	final int SHADOWMAP_SIZE=2048;
	DirectionalLightShadowFilter sunshadow = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 4);
	sunshadow.setLight(sunlight);
	sunshadow.setEdgeFilteringMode(EdgeFilteringMode.PCF8);
	fpp.addFilter(sunshadow);

and finally for the planet:

Geometry geo = planetGeo.clone();
	
	geo.setName(planet.getName());
	geo.setLocalTranslation(0, 0, 0);
	geo.scale((float)planet.getRadius());
	
	geo.setMaterial(planet.getMaterial());	
	geo.setShadowMode(ShadowMode.Cast);

I’d love to hear any ideas or solutions! The only thing that helped a tiny little bit was reducing the shadow map resolution to 512, but that didn’t exactly improve the quality and didn’t do anything to make the shadows soft…

Try to use DirectionalLightShadowRenderer instead of ShadowFilter.

It appears to me, that the shadow bias is too small. As far as I remember this value is handled through polygon offset values in the shadows’ .j3md material definition file, in the shadow techniques. I do not know if you can set the bias by calling a method, but this gives you a point to start investigating.

The outcome of the polygon offset may also be influenced by the view frustum’s near-far distance. As you’re working on a space game this could be an issue.

Using DirectionalLightShadowRenderer does reduce the flickering. But now the shadows look like this, any idea what I should do? :confused:

@Apollo: what is the shadow bias? how can I modify that? As for the frustum, I dynamically scale the planets so that they always fall inside it, the near-far distances are 0.05 to 15000. If I increase the near distance to 10 the shadows do improve quite a bit! But that’s only with the ShadowFilter, there’s no change when using ShadowRenderer.

Edit: I changed the near and far distances tot 0.1 and 1500, which work for me (changed the dynamic scaling a bit and this should be no problem). Thanks! Then there only remains two smaller questions. First: the shadows still look a bit jagged, is there a way I can easily fix that?

And secondly, Is there a way to drop shadows of the rings onto the planet? So using the alpha values of the material applied to the ring-quad.

For a basic introduction on shadow mapping and artifacts visit this tutorial: (it also covers the bias value)
http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/

There are more advanced methods to improve shadow quality but JME does not offer them yet.

Your far/near ratio should not exceed 50000 (if I remember correctly). You could adjust the bias by changing the polyoffset values in the .j3md files (or making your own j3md files, which is much cleaner).

As for your first question, you could increase shadow map size. The second question is the one I cannot answer, since I never used JME’s shadow system, but maybe someone else knows how to do this?