diff options
Diffstat (limited to 'engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java')
-rw-r--r-- | engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java b/engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java new file mode 100644 index 0000000..953f10a --- /dev/null +++ b/engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 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 + * notice, this list of conditions and the following disclaimer. + * + * * 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 + * 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 com.jme3.post.filters; + +import com.jme3.asset.AssetManager; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.post.Filter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import java.io.IOException; + +/** + * LightScattering filters creates rays comming from a light sources + * This is often reffered as god rays. + * + * @author Rémy Bouquet aka Nehon + */ +public class LightScatteringFilter extends Filter { + + private Vector3f lightPosition; + private Vector3f screenLightPos = new Vector3f(); + private int nbSamples = 50; + private float blurStart = 0.02f; + private float blurWidth = 0.9f; + private float lightDensity = 1.4f; + private boolean adaptative = true; + Vector3f viewLightPos = new Vector3f(); + private boolean display = true; + private float innerLightDensity; + + /** + * creates a lightScaterring filter + */ + public LightScatteringFilter() { + super("Light Scattering"); + } + + /** + * Creates a lightScatteringFilter + * @param lightPosition + */ + public LightScatteringFilter(Vector3f lightPosition) { + this(); + this.lightPosition = lightPosition; + } + + @Override + protected boolean isRequiresDepthTexture() { + return true; + } + + @Override + protected Material getMaterial() { + material.setVector3("LightPosition", screenLightPos); + material.setInt("NbSamples", nbSamples); + material.setFloat("BlurStart", blurStart); + material.setFloat("BlurWidth", blurWidth); + material.setFloat("LightDensity", innerLightDensity); + material.setBoolean("Display", display); + return material; + } + + @Override + protected void postQueue(RenderManager renderManager, ViewPort viewPort) { + getClipCoordinates(lightPosition, screenLightPos, viewPort.getCamera()); + // screenLightPos.x = screenLightPos.x / viewPort.getCamera().getWidth(); + // screenLightPos.y = screenLightPos.y / viewPort.getCamera().getHeight(); + + viewPort.getCamera().getViewMatrix().mult(lightPosition, viewLightPos); + //System.err.println("viewLightPos "+viewLightPos); + display = screenLightPos.x < 1.6f && screenLightPos.x > -0.6f && screenLightPos.y < 1.6f && screenLightPos.y > -0.6f && viewLightPos.z < 0; +//System.err.println("camdir "+viewPort.getCamera().getDirection()); +//System.err.println("lightPos "+lightPosition); +//System.err.println("screenLightPos "+screenLightPos); + if (adaptative) { + innerLightDensity = Math.max(lightDensity - Math.max(screenLightPos.x, screenLightPos.y), 0.0f); + } else { + innerLightDensity = lightDensity; + } + } + + private Vector3f getClipCoordinates(Vector3f worldPosition, Vector3f store, Camera cam) { + + float w = cam.getViewProjectionMatrix().multProj(worldPosition, store); + store.divideLocal(w); + + store.x = ((store.x + 1f) * (cam.getViewPortRight() - cam.getViewPortLeft()) / 2f + cam.getViewPortLeft()); + store.y = ((store.y + 1f) * (cam.getViewPortTop() - cam.getViewPortBottom()) / 2f + cam.getViewPortBottom()); + store.z = (store.z + 1f) / 2f; + + return store; + } + + @Override + protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) { + material = new Material(manager, "Common/MatDefs/Post/LightScattering.j3md"); + } + + /** + * returns the blur start of the scattering + * see {@link setBlurStart(float blurStart)} + * @return + */ + public float getBlurStart() { + return blurStart; + } + + /** + * sets the blur start<br> + * at which distance from the light source the effect starts default is 0.02 + * @param blurStart + */ + public void setBlurStart(float blurStart) { + this.blurStart = blurStart; + } + + /** + * returns the blur width<br> + * see {@link setBlurWidth(float blurWidth)} + * @return + */ + public float getBlurWidth() { + return blurWidth; + } + + /** + * sets the blur width default is 0.9 + * @param blurWidth + */ + public void setBlurWidth(float blurWidth) { + this.blurWidth = blurWidth; + } + + /** + * retiurns the light density<br> + * see {@link setLightDensity(float lightDensity)} + * + * @return + */ + public float getLightDensity() { + return lightDensity; + } + + /** + * sets how much the effect is visible over the rendered scene default is 1.4 + * @param lightDensity + */ + public void setLightDensity(float lightDensity) { + this.lightDensity = lightDensity; + } + + /** + * returns the light position + * @return + */ + public Vector3f getLightPosition() { + return lightPosition; + } + + /** + * sets the light position + * @param lightPosition + */ + public void setLightPosition(Vector3f lightPosition) { + this.lightPosition = lightPosition; + } + + /** + * returns the nmber of samples for the radial blur + * @return + */ + public int getNbSamples() { + return nbSamples; + } + + /** + * sets the number of samples for the radial blur default is 50 + * the higher the value the higher the quality, but the slower the performances. + * @param nbSamples + */ + public void setNbSamples(int nbSamples) { + this.nbSamples = nbSamples; + } + + @Override + public void write(JmeExporter ex) throws IOException { + super.write(ex); + OutputCapsule oc = ex.getCapsule(this); + oc.write(lightPosition, "lightPosition", Vector3f.ZERO); + oc.write(nbSamples, "nbSamples", 50); + oc.write(blurStart, "blurStart", 0.02f); + oc.write(blurWidth, "blurWidth", 0.9f); + oc.write(lightDensity, "lightDensity", 1.4f); + oc.write(adaptative, "adaptative", true); + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule ic = im.getCapsule(this); + lightPosition = (Vector3f) ic.readSavable("lightPosition", Vector3f.ZERO); + nbSamples = ic.readInt("nbSamples", 50); + blurStart = ic.readFloat("blurStart", 0.02f); + blurWidth = ic.readFloat("blurWidth", 0.9f); + lightDensity = ic.readFloat("lightDensity", 1.4f); + adaptative = ic.readBoolean("adaptative", true); + } +} |