Well i have the problem that I need a very large far frustrum distance, so basically everything is in the first split for a far to long distance. I already looked at the code but did not understood where exactly it decided which split to use so i could change i in a way that the first 50 meters it is first split then second for the next 200 , 3 for up to 5 km and last for the rest.
Another solution would be to tell the PPSM that I only need shadows in the first few hundred meters (after that there is not much need for details anyway)
Is something similar like this possible?
You can tweak the lambda factor of the renderer.
It controls the repartition of the split in the frustum.
If you use a 0 value, you’ll have a linear repartition, for example for a 1000 unit farFrustum value and 4 splits you’ll have a split every 250 units. But seams between splits will be very visible.
With a 1 value, the repartition is logarithmic and seams are invisible, but quality decrease very quickly with distance.
the default value is 0.65.
Thanks, that works quite good, now I finally have a good resolution around the cam.
One more question tho, I sometims have objects side exactly with the same direction as the direction the pass uses, these flicker when I move, is there a good tip to surpress this?
mhhh, are your objects in physic space by any chance?
Anyway, i’m afraid it’s a bug, maybe related to the this issue http://code.google.com/p/jmonkeyengine/issues/detail?id=234&q=label%3AProduct-jME3&colspec=ID%20Type%20Status%20Component%20Priority%20Product%20Milestone%20Owner%20Summary
One more thing in the todo list I guess
Nope they are not*, however the light is the same direction,
What i suspect:
I always have some edgy lines on objects when I’m near them (like in the test with the teapots) now when I move those move a slowly as well. I suspect that these edges are in ase of a 90degree betwenn side an direction are sometimes over the edge sometimes not. so the whole wall flickers as it basically only have one small point of the shadowmap on it.
I guess the Problem might be the same as in the other thread, but the reason is not the BulletPhysicState, but something else. If it helps, all of my objects are in a Node attached to a Node wich itself is then attached to the rootnode. Setting the light to be slightly from the side greatly reduces the issue, but does not fix it completly
*Actually there is a remote physicsystem involved, but the object I have the problem with does not move at any time.(Except maybee a few acuarcy issues depending on camera movement)
could you try to use a PCF filtering with the pssmRenderer and set it to the max
if you have one pixel and that it’s causing the flickering, smoothing it with PCF should reduce the issue, and we’ll know where the problem comes from.
Hm thats only helping a bit.
I will record a video in the evening, maybee that helps you to determine what might cause this.
Ok, my pc hates to amke screenvideos as it seems, I will instead try to explain as good as I can:
Below is a modified PPSM shadow test.
The boxes use the light amterial but no light in scene is specified, so only the shadows can be seen.
There are when moving around two problems visible:
→ Sometimes the sides of a few boxes flicker dark black this is exactly my current problem (but for sides of models instead)
→ The ground shadows seems to be visible through the boxes? Not sure if this is related tho.
/*
- Copyright © 2009-2010 jMonkeyEngine
- All rights reserved.
*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
*
-
- Redistributions of source code must retain the above copyright
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
*
-
- Redistributions in binary form must reproduce the above copyright
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
*
-
- Neither the name of ‘jMonkeyEngine’ nor the names of its contributors
- Neither the name of ‘jMonkeyEngine’ nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
*
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.light;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.shadow.PssmShadowRenderer;
import com.jme3.shadow.PssmShadowRenderer.CompareMode;
import com.jme3.shadow.PssmShadowRenderer.FilterMode;
import java.awt.Color;
import java.util.Random;
public class TestPssmShadow extends SimpleApplication implements ActionListener {
private Spatial teapot;
private boolean renderShadows = true;
private boolean hardwareShadows = false;
private PssmShadowRenderer pssmRenderer;
public static void main(String[] args){
TestPssmShadow app = new TestPssmShadow();
app.start();
}
public void loadScene(){
viewPort.setBackgroundColor(ColorRGBA.White);
Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md");
mat.setColor("Diffuse",ColorRGBA.Red);
Material matSoil = new Material(assetManager,"Common/MatDefs/Misc/SolidColor.j3md");
matSoil.setColor("Color", ColorRGBA.Cyan);
teapot = new Geometry("sphere", new Box(1,1,1));
// teapot = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f));
// teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
teapot.setLocalTranslation(0,0,10);
teapot.setMaterial(mat);
teapot.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(teapot);
long seed = 1294719330150L; //System.currentTimeMillis();
Random random = new Random(seed);
System.out.println(seed);
for (int i = 0; i < 30; i++) {
Spatial t = teapot.clone(false);
rootNode.attachChild(t);
teapot.setLocalTranslation((float) random.nextFloat() * 3, (float) random.nextFloat() * 3, (i + 2));
}
Geometry soil = new Geometry("soil", new Box(new Vector3f(0, -13, 550), 800, 10, 700));
soil.setMaterial(matSoil);
soil.setShadowMode(ShadowMode.Receive);
rootNode.attachChild(soil);
for (int i = 0; i < 30; i++) {
Spatial t = teapot.clone(false);
t.setLocalScale(10.0f);
rootNode.attachChild(t);
teapot.setLocalTranslation((float) random.nextFloat() * 300, (float) random.nextFloat() * 30, 30 * (i + 2));
}
}
@Override
public void simpleInitApp() {
// put the camera in a bad position
cam.setLocation(new Vector3f(0f,0,-100));
cam.setRotation(new Quaternion(0,0,0,1));
flyCam.setMoveSpeed(100);
loadScene();
pssmRenderer = new PssmShadowRenderer(assetManager, 1024, 3);
pssmRenderer.setDirection(new Vector3f(0, -1, 0).normalizeLocal());
pssmRenderer.setLambda(0.55f);
pssmRenderer.setShadowIntensity(1f);
pssmRenderer.setCompareMode(CompareMode.Hardware);
pssmRenderer.setFilterMode(FilterMode.PCF8);
pssmRenderer.displayDebug();
viewPort.addProcessor(pssmRenderer);
initInputs();
}
private void initInputs() {
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("ShadowUp", new KeyTrigger(KeyInput.KEY_T));
inputManager.addMapping("ShadowDown", new KeyTrigger(KeyInput.KEY_G));
inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y));
inputManager.addMapping("ThicknessDown", new KeyTrigger(KeyInput.KEY_H));
inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U));
inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping("toggleHW", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "lambdaUp", "lambdaDown", "toggleHW", "toggle", "ShadowUp","ShadowDown","ThicknessUp","ThicknessDown");
}
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("toggle") && keyPressed) {
if (renderShadows) {
renderShadows = false;
viewPort.removeProcessor(pssmRenderer);
} else {
renderShadows = true;
viewPort.addProcessor(pssmRenderer);
}
} else if (name.equals("toggleHW") && keyPressed) {
hardwareShadows = !hardwareShadows;
pssmRenderer.setCompareMode(hardwareShadows ? CompareMode.Hardware : CompareMode.Software);
System.out.println("HW Shadows: " + hardwareShadows);
}
if (name.equals("lambdaUp") && keyPressed) {
pssmRenderer.setLambda(pssmRenderer.getLambda() + 0.01f);
System.out.println("Lambda : " + pssmRenderer.getLambda());
} else if (name.equals("lambdaDown") && keyPressed) {
pssmRenderer.setLambda(pssmRenderer.getLambda() - 0.01f);
System.out.println("Lambda : " + pssmRenderer.getLambda());
}
if (name.equals("ShadowUp") && keyPressed) {
pssmRenderer.setShadowIntensity(pssmRenderer.getShadowIntensity() + 0.1f);
System.out.println("Shadow intensity : " + pssmRenderer.getShadowIntensity());
}
if (name.equals("ShadowDown") && keyPressed) {
pssmRenderer.setShadowIntensity(pssmRenderer.getShadowIntensity() - 0.1f);
System.out.println("Shadow intensity : " + pssmRenderer.getShadowIntensity());
}
if (name.equals("ThicknessUp") && keyPressed) {
pssmRenderer.setEdgesThickness(pssmRenderer.getEdgesThickness() + 1);
System.out.println("Shadow thickness : " + pssmRenderer.getEdgesThickness());
}
if (name.equals("ThicknessDown") && keyPressed) {
pssmRenderer.setEdgesThickness(pssmRenderer.getEdgesThickness() - 1);
System.out.println("Shadow thickness : " + pssmRenderer.getEdgesThickness());
}
}
}
ok thanks i’ll look into this test case