aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java
diff options
context:
space:
mode:
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.java243
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);
+ }
+}