import java.util.ArrayList;
/**
- *
- * @author nehon
+ * SSAO stands for screen space ambient occlusion
+ * It's a technique that fake ambient lighting by computind shadows that near by objects would casts on each others
+ * under the effect of an ambient light
+ * more info on this in this blog post http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/
+ *
+ * @author Rémy Bouquet aka Nehon
*/
public class SSAOFilter extends Filter {
private boolean useAo = true;
private Material ssaoMat;
private Pass ssaoPass;
- private Material downSampleMat;
- private Pass downSamplePass;
+// private Material downSampleMat;
+// private Pass downSamplePass;
private float downSampleFactor = 1f;
/**
}
/**
- *
- * @param vp
- * @param sampleRadius
- * @param intensity
- * @param scale
- * @param bias
+ * Create a Screen Space Ambiant Occlusion Filter
+ * @param sampleRadius The radius of the area where random samples will be picked. default 5.1f
+ * @param intensity intensity of the resulting AO. default 1.2f
+ * @param scale distance between occluders and occludee. default 0.2f
+ * @param bias the width of the occlusion cone considered by the occludee. default 0.1f
*/
public SSAOFilter(float sampleRadius, float intensity, float scale, float bias) {
this();
postRenderPasses = new ArrayList<Pass>();
normalPass = new Pass();
- normalPass.init(renderManager.getRenderer(), (int)(screenWidth / downSampleFactor), (int)(screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);
+ normalPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);
frustumNearFar = new Vector2f();
}
};
- ssaoPass.init(renderManager.getRenderer(), (int)(screenWidth / downSampleFactor), (int)(screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
+ ssaoPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
postRenderPasses.add(ssaoPass);
}
+ /**
+ * Return the bias<br>
+ * see {@link setBias(float bias)}
+ * @return
+ */
public float getBias() {
return bias;
}
+ /**
+ * Sets the the width of the occlusion cone considered by the occludee default is 0.1f
+ * @param bias
+ */
public void setBias(float bias) {
this.bias = bias;
if (ssaoMat != null) {
}
}
+ /**
+ * returns the ambient occlusion intensity
+ * @return
+ */
public float getIntensity() {
return intensity;
}
+ /**
+ * Sets the Ambient occlusion intensity default is 1.2f
+ * @param intensity
+ */
public void setIntensity(float intensity) {
this.intensity = intensity;
if (ssaoMat != null) {
}
+ /**
+ * returns the sample radius<br>
+ * see {link setSampleRadius(float sampleRadius)}
+ * @return
+ */
public float getSampleRadius() {
return sampleRadius;
}
+ /**
+ * Sets the radius of the area where random samples will be picked dafault 5.1f
+ * @param sampleRadius
+ */
public void setSampleRadius(float sampleRadius) {
this.sampleRadius = sampleRadius;
if (ssaoMat != null) {
}
+ /**
+ * returns the scale<br>
+ * see {@link setScale(float scale)}
+ * @return
+ */
public float getScale() {
return scale;
}
+ /**
+ *
+ * Returns the distance between occluders and occludee. dafault 0.2f
+ * @param scale
+ */
public void setScale(float scale) {
this.scale = scale;
if (ssaoMat != null) {
ssaoMat.setFloat("Scale", scale);
}
-
}
+ /**
+ * debugging only , will be removed
+ * @return
+ */
public boolean isUseAo() {
return useAo;
}
+ /**
+ * debugging only , will be removed
+ * @return
+ */
public void setUseAo(boolean useAo) {
this.useAo = useAo;
if (material != null) {
}
+ /**
+ * debugging only , will be removed
+ * @return
+ */
public boolean isUseOnlyAo() {
return useOnlyAo;
}
+ /**
+ * debugging only , will be removed
+ * @return
+ */
public void setUseOnlyAo(boolean useOnlyAo) {
this.useOnlyAo = useOnlyAo;
if (material != null) {
scale = ic.readFloat("scale", 0.2f);
bias = ic.readFloat("bias", 0.1f);
}
-
-
}
private FrameBuffer reflectionBuffer;
private Plane reflectionClipPlane;
+ /**
+ * Creates a ReflectionProcessor
+ * @param reflectionCam the cam to use for reflection
+ * @param reflectionBuffer the FrameBuffer to render to
+ * @param reflectionClipPlane the clipping plane
+ */
public ReflectionProcessor(Camera reflectionCam, FrameBuffer reflectionBuffer, Plane reflectionClipPlane) {
this.reflectionCam = reflectionCam;
this.reflectionBuffer = reflectionBuffer;
public void cleanup() {
}
+ /**
+ * Internal use only<br>
+ * returns the frame buffer
+ * @return
+ */
public FrameBuffer getReflectionBuffer() {
return reflectionBuffer;
}
+ /**
+ * Internal use only<br>
+ * sets the frame buffer
+ * @param reflectionBuffer
+ */
public void setReflectionBuffer(FrameBuffer reflectionBuffer) {
this.reflectionBuffer = reflectionBuffer;
}
+ /**
+ * returns the reflection cam
+ * @return
+ */
public Camera getReflectionCam() {
return reflectionCam;
}
+ /**
+ * sets the reflection cam
+ * @param reflectionCam
+ */
public void setReflectionCam(Camera reflectionCam) {
this.reflectionCam = reflectionCam;
}
+ /**
+ * returns the reflection clip plane
+ * @return
+ */
public Plane getReflectionClipPlane() {
return reflectionClipPlane;
}
+ /**
+ * Sets the reflection clip plane
+ * @param reflectionClipPlane
+ */
public void setReflectionClipPlane(Plane reflectionClipPlane) {
this.reflectionClipPlane = reflectionClipPlane;
}
import com.jme3.scene.shape.Quad;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
-import com.jme3.texture.Texture.MagFilter;
-import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.texture.Texture2D;
import com.jme3.ui.Picture;
-import com.jme3.util.TempVars;
/**
*
- * @author normenhansen
+ * Simple Water renders a simple plane that use reflection and refraction to look like water.
+ * It's pretty basic, but much faster than the WaterFilter
+ * It's useful if you aim low specs hardware and still want a good looking water.
+ * Usage is :
+ * <code>
+ * SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
+ * //setting the scene to use for reflection
+ * waterProcessor.setReflectionScene(mainScene);
+ * //setting the light position
+ * waterProcessor.setLightPosition(lightPos);
+ *
+ * //setting the water plane
+ * Vector3f waterLocation=new Vector3f(0,-20,0);
+ * waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
+ * //setting the water color
+ * waterProcessor.setWaterColor(ColorRGBA.Brown);
+ *
+ * //creating a quad to render water to
+ * Quad quad = new Quad(400,400);
+ *
+ * //the texture coordinates define the general size of the waves
+ * quad.scaleTextureCoordinates(new Vector2f(6f,6f));
+ *
+ * //creating a geom to attach the water material
+ * Geometry water=new Geometry("water", quad);
+ * water.setLocalTranslation(-200, -20, 250);
+ * water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
+ * //finally setting the material
+ * water.setMaterial(waterProcessor.getMaterial());
+ *
+ * //attaching the water to the root node
+ * rootNode.attachChild(water);
+ * </code>
+ * @author Normen Hansen & Rémy Bouquet
*/
public class SimpleWaterProcessor implements SceneProcessor {
private Vector3f vect2 = new Vector3f();
private Vector3f vect3 = new Vector3f();
+ /**
+ * Creates a SimpleWaterProcessor
+ * @param manager the asset manager
+ */
public SimpleWaterProcessor(AssetManager manager) {
this.manager = manager;
material = new Material(manager, "Common/MatDefs/Water/SimpleWater.j3md");
reflectionScene = spat;
}
+ /**
+ * returns the width of the reflection and refraction textures
+ * @return
+ */
public int getRenderWidth() {
return renderWidth;
}
+ /**
+ * returns the height of the reflection and refraction textures
+ * @return
+ */
public int getRenderHeight() {
return renderHeight;
}
renderHeight = height;
}
+ /**
+ * returns the water plane
+ * @return
+ */
public Plane getPlane() {
return plane;
}
material.setFloat("waterDepth", depth);
}
+ /**
+ * return the water depth
+ * @return
+ */
public float getWaterDepth() {
return waterDepth;
}
+ /**
+ * returns water transparency
+ * @return
+ */
public float getWaterTransparency() {
return waterTransparency;
}
+ /**
+ * sets the water transparency default os 0.1f
+ * @param waterTransparency
+ */
public void setWaterTransparency(float waterTransparency) {
this.waterTransparency = Math.max(0, waterTransparency);
material.setFloat("waterTransparency", waterTransparency / 10);
material.setColor("texScale", new ColorRGBA(value, value, value, value));
}
+ /**
+ * retruns true if the waterprocessor is in debug mode
+ * @return
+ */
public boolean isDebug() {
return debug;
}
+ /**
+ * set to true to display reflection and refraction textures in the GUI for debug purpose
+ * @param debug
+ */
public void setDebug(boolean debug) {
this.debug = debug;
}
import com.jme3.post.Filter.Pass;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.Renderer;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import java.io.IOException;
/**
- *
- * @author nehon
+ * The WaterFilter is a 2D post process that simulate water.
+ * It renders water above and under water.
+ * See this blog post for more info http://jmonkeyengine.org/2011/01/15/new-advanced-water-effect-for-jmonkeyengine-3/
+ *
+ *
+ * @author Rémy Bouquet aka Nehon
*/
public class WaterFilter extends Filter {
}
+ /**
+ * returns true if the water use the refraction
+ * @return
+ */
public boolean isUseRefraction() {
return useRefraction;
}
+ /**
+ * set to true to use refraction (default is true)
+ * @param useRefraction
+ */
public void setUseRefraction(boolean useRefraction) {
this.useRefraction = useRefraction;
if (material != null) {
}
+ /**
+ * returns true if the ater use ripples
+ * @return
+ */
public boolean isUseRipples() {
return useRipples;
}
+ /**
+ *
+ * Set to true tu use ripples
+ * @param useRipples
+ */
public void setUseRipples(boolean useRipples) {
this.useRipples = useRipples;
if (material != null) {
}
+ /**
+ * returns true if the water use specular
+ * @return
+ */
public boolean isUseSpecular() {
return useSpecular;
}
+ /**
+ * Set to true to use specular lightings on the water
+ * @param useSpecular
+ */
public void setUseSpecular(boolean useSpecular) {
this.useSpecular = useSpecular;
if (material != null) {
}
}
+ /**
+ * returns the foam intensity
+ * @return
+ */
public float getFoamIntensity() {
return foamIntensity;
}
+ /**
+ * sets the foam intensity default is 0.5f
+ * @param foamIntensity
+ */
public void setFoamIntensity(float foamIntensity) {
this.foamIntensity = foamIntensity;
if (material != null) {
}
}
+ /**
+ * returns the reflection displace
+ * see {@link setReflectionDisplace(float reflectionDisplace)}
+ * @return
+ */
public float getReflectionDisplace() {
return reflectionDisplace;
}
+ /**
+ * Sets the reflection displace. define how troubled will look the reflection in the water. default is 30
+ * @param reflectionDisplace
+ */
public void setReflectionDisplace(float reflectionDisplace) {
this.reflectionDisplace = reflectionDisplace;
if (material != null) {