Hey guys,
I know that there have already been some topics on this but I cannot get this to work. I have grass which consists of multiple quads with partly transparent png textures. I now want them to receive shadows and I built a simple testcase for that. This is the code:
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Quad;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.util.BufferUtils;
import com.jme3.util.TangentBinormalGenerator;
/**
* test
*
* @author normenhansen
*/
public class Main extends SimpleApplication {
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
cam.setLocation(new Vector3f(0,30,0));
flyCam.setMoveSpeed(50);
Spatial terrain = assetManager.loadModel("Scenes/newScene.j3o");
rootNode.attachChild(terrain);
/**
* A white ambient light source.
*/
AmbientLight ambient = new AmbientLight();
ambient.setColor(ColorRGBA.White);
rootNode.addLight(ambient);
/**
* A white, directional light source
*/
DirectionalLight sun = new DirectionalLight();
sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
sun.setColor(ColorRGBA.White);
rootNode.addLight(sun);
/* this shadow needs a directional light */
DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, 1024, 2);
dlsr.setLight(sun);
viewPort.addProcessor(dlsr);
rootNode.attachChild(getGrassNode());
Node n = getGrassNode();
n.setLocalTranslation(-18.131676f, 0.0f, -18.806698f);
rootNode.attachChild(n);
}
private Node getGrassNode() {
Quad quad = new Quad(5, 5);
Node grassNode = new Node();
Geometry geom = new Geometry("grass", quad);
float[] normals = new float[]{0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
geom.getMesh().setBuffer(VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
geom.setShadowMode(RenderQueue.ShadowMode.Receive);
grassNode.attachChild(geom);
grassNode.setShadowMode(RenderQueue.ShadowMode.Receive);
grassNode.setCullHint(Spatial.CullHint.Dynamic);
Material grassMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
// grassMat.setColor("Diffuse", ColorRGBA.Green);
// grassMat.setColor("Ambient", ColorRGBA.Green);
// grassMat.setBoolean("UseMaterialColors", true);
grassMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/billboardGrass.png"));
grassMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
grassMat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
grassMat.setFloat("AlphaDiscardThreshold", .5f);
grassNode.setMaterial(grassMat);
grassNode.setLocalTranslation(-18.131676f, 0.0f, -10.806698f);
return grassNode;
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
So I get different results, but not the one I want to achieve. First I tested it without the texture:
That’s the code for that, looking fine so far:
Material grassMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
grassMat.setColor("Diffuse", ColorRGBA.Green);
grassMat.setColor("Ambient", ColorRGBA.Green);
grassMat.setBoolean("UseMaterialColors", true);
// grassMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/billboardGrass.png"));
grassMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
grassMat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
// grassMat.setFloat("AlphaDiscardThreshold", .5f);
Now as soon as I set the AlphaDiscardThreshold to any number:
The shadow is somehow not applied once I set the AlphaDiscardThreshold…
Okay, let’s try it with a texture.
Material grassMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
// grassMat.setColor("Diffuse", ColorRGBA.Green);
// grassMat.setColor("Ambient", ColorRGBA.Green);
// grassMat.setBoolean("UseMaterialColors", true);
grassMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/billboardGrass.png"));
grassMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
grassMat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
// grassMat.setFloat("AlphaDiscardThreshold", .5f);
That’s not looking good. With AlphaDiscardThreshold set:
Looking okay, but the shadow is not applied at all - the same when I use no texture. How can I have a result as in the last image but with a visible shadow on the quad?