|
@@ -50,17 +50,19 @@ import com.jme3.scene.Spatial;
|
|
import com.jme3.texture.TextureCubeMap;
|
|
import com.jme3.texture.TextureCubeMap;
|
|
import com.jme3.util.TempVars;
|
|
import com.jme3.util.TempVars;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.util.logging.Level;
|
|
|
|
+import java.util.logging.Logger;
|
|
|
|
|
|
/**
|
|
/**
|
|
* A LightProbe is not exactly a light. It holds environment map information used for Image Based Lighting.
|
|
* A LightProbe is not exactly a light. It holds environment map information used for Image Based Lighting.
|
|
* This is used for indirect lighting in the Physically Based Rendering pipeline.
|
|
* This is used for indirect lighting in the Physically Based Rendering pipeline.
|
|
*
|
|
*
|
|
* A light probe has a position in world space. This is the position from where the Environment Map are rendered.
|
|
* A light probe has a position in world space. This is the position from where the Environment Map are rendered.
|
|
- * There are two environment maps held by the LightProbe :
|
|
|
|
- * - The irradiance map (used for indirect diffuse lighting in the PBR pipeline).
|
|
|
|
|
|
+ * There are two environment data structure held by the LightProbe :
|
|
|
|
+ * - The irradiance spherical harmonics factors (used for indirect diffuse lighting in the PBR pipeline).
|
|
* - The prefiltered environment map (used for indirect specular lighting and reflection in the PBE pipeline).
|
|
* - The prefiltered environment map (used for indirect specular lighting and reflection in the PBE pipeline).
|
|
- * Note that when instanciating the LightProbe, both those maps are null.
|
|
|
|
- * To render them see {@link LightProbeFactory#makeProbe(com.jme3.environment.EnvironmentCamera, com.jme3.scene.Node)}
|
|
|
|
|
|
+ * Note that when instantiating the LightProbe, both of those structures are null.
|
|
|
|
+ * To compute them see {@link LightProbeFactory#makeProbe(com.jme3.environment.EnvironmentCamera, com.jme3.scene.Node)}
|
|
* and {@link EnvironmentCamera}.
|
|
* and {@link EnvironmentCamera}.
|
|
*
|
|
*
|
|
* The light probe has an area of effect that is a bounding volume centered on its position. (for now only Bounding spheres are supported).
|
|
* The light probe has an area of effect that is a bounding volume centered on its position. (for now only Bounding spheres are supported).
|
|
@@ -75,7 +77,9 @@ import java.io.IOException;
|
|
*/
|
|
*/
|
|
public class LightProbe extends Light implements Savable {
|
|
public class LightProbe extends Light implements Savable {
|
|
|
|
|
|
- private TextureCubeMap irradianceMap;
|
|
|
|
|
|
+ private static final Logger logger = Logger.getLogger(LightProbe.class.getName());
|
|
|
|
+
|
|
|
|
+ private Vector3f[] shCoeffs;
|
|
private TextureCubeMap prefilteredEnvMap;
|
|
private TextureCubeMap prefilteredEnvMap;
|
|
private BoundingVolume bounds = new BoundingSphere(1.0f, Vector3f.ZERO);
|
|
private BoundingVolume bounds = new BoundingSphere(1.0f, Vector3f.ZERO);
|
|
private boolean ready = false;
|
|
private boolean ready = false;
|
|
@@ -90,23 +94,6 @@ public class LightProbe extends Light implements Savable {
|
|
public LightProbe() {
|
|
public LightProbe() {
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * returns the irradiance map texture of this Light probe.
|
|
|
|
- * Note that this Texture may not have image data yet if the LightProbe is not ready
|
|
|
|
- * @return the irradiance map
|
|
|
|
- */
|
|
|
|
- public TextureCubeMap getIrradianceMap() {
|
|
|
|
- return irradianceMap;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Sets the irradiance map
|
|
|
|
- * @param irradianceMap the irradiance map
|
|
|
|
- */
|
|
|
|
- public void setIrradianceMap(TextureCubeMap irradianceMap) {
|
|
|
|
- this.irradianceMap = irradianceMap;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* returns the prefiltered environment map texture of this light probe
|
|
* returns the prefiltered environment map texture of this light probe
|
|
* Note that this Texture may not have image data yet if the LightProbe is not ready
|
|
* Note that this Texture may not have image data yet if the LightProbe is not ready
|
|
@@ -128,7 +115,7 @@ public class LightProbe extends Light implements Savable {
|
|
public void write(JmeExporter ex) throws IOException {
|
|
public void write(JmeExporter ex) throws IOException {
|
|
super.write(ex);
|
|
super.write(ex);
|
|
OutputCapsule oc = ex.getCapsule(this);
|
|
OutputCapsule oc = ex.getCapsule(this);
|
|
- oc.write(irradianceMap, "irradianceMap", null);
|
|
|
|
|
|
+ oc.write(shCoeffs, "shCoeffs", null);
|
|
oc.write(prefilteredEnvMap, "prefilteredEnvMap", null);
|
|
oc.write(prefilteredEnvMap, "prefilteredEnvMap", null);
|
|
oc.write(position, "position", null);
|
|
oc.write(position, "position", null);
|
|
oc.write(bounds, "bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
|
|
oc.write(bounds, "bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
|
|
@@ -139,11 +126,15 @@ public class LightProbe extends Light implements Savable {
|
|
public void read(JmeImporter im) throws IOException {
|
|
public void read(JmeImporter im) throws IOException {
|
|
super.read(im);
|
|
super.read(im);
|
|
InputCapsule ic = im.getCapsule(this);
|
|
InputCapsule ic = im.getCapsule(this);
|
|
- irradianceMap = (TextureCubeMap) ic.readSavable("irradianceMap", null);
|
|
|
|
|
|
+ shCoeffs = (Vector3f[]) ic.readSavableArray("shCoeffs", null);
|
|
prefilteredEnvMap = (TextureCubeMap) ic.readSavable("prefilteredEnvMap", null);
|
|
prefilteredEnvMap = (TextureCubeMap) ic.readSavable("prefilteredEnvMap", null);
|
|
position = (Vector3f) ic.readSavable("position", this);
|
|
position = (Vector3f) ic.readSavable("position", this);
|
|
bounds = (BoundingVolume) ic.readSavable("bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
|
|
bounds = (BoundingVolume) ic.readSavable("bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
|
|
ready = ic.readBoolean("ready", false);
|
|
ready = ic.readBoolean("ready", false);
|
|
|
|
+ if (shCoeffs == null) {
|
|
|
|
+ ready = false;
|
|
|
|
+ logger.log(Level.WARNING, "LightProbe is missing parameters, it should be recomputed. Please use lightProbeFactory.updateProbe()");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -195,14 +186,11 @@ public class LightProbe extends Light implements Savable {
|
|
*/
|
|
*/
|
|
public Node getDebugGui(AssetManager manager) {
|
|
public Node getDebugGui(AssetManager manager) {
|
|
if (!ready) {
|
|
if (!ready) {
|
|
- throw new UnsupportedOperationException("This EnvProbeis not ready yet, try to test isReady()");
|
|
|
|
|
|
+ throw new UnsupportedOperationException("This EnvProbe is not ready yet, try to test isReady()");
|
|
}
|
|
}
|
|
if (debugNode == null) {
|
|
if (debugNode == null) {
|
|
debugNode = new Node("debug gui probe");
|
|
debugNode = new Node("debug gui probe");
|
|
Node debugPfemCm = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(getPrefilteredEnvMap(), manager);
|
|
Node debugPfemCm = EnvMapUtils.getCubeMapCrossDebugViewWithMipMaps(getPrefilteredEnvMap(), manager);
|
|
- Node debugIrrCm = EnvMapUtils.getCubeMapCrossDebugView(getIrradianceMap(), manager);
|
|
|
|
-
|
|
|
|
- debugNode.attachChild(debugIrrCm);
|
|
|
|
debugNode.attachChild(debugPfemCm);
|
|
debugNode.attachChild(debugPfemCm);
|
|
debugPfemCm.setLocalTranslation(520, 0, 0);
|
|
debugPfemCm.setLocalTranslation(520, 0, 0);
|
|
}
|
|
}
|
|
@@ -210,6 +198,14 @@ public class LightProbe extends Light implements Savable {
|
|
return debugNode;
|
|
return debugNode;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public Vector3f[] getShCoeffs() {
|
|
|
|
+ return shCoeffs;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setShCoeffs(Vector3f[] shCoeffs) {
|
|
|
|
+ this.shCoeffs = shCoeffs;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Returns the position of the LightProbe in world space
|
|
* Returns the position of the LightProbe in world space
|
|
* @return the wolrd space position
|
|
* @return the wolrd space position
|