EnvironmentProbeControl, for simpler env baking

accellbaker
Riccardo Balbo 5 years ago
parent c91b2dd3f0
commit ec01833fa1
  1. 104
      jme3-core/src/main/java/com/jme3/environment/EnvironmentProbeControl.java
  2. 3
      jme3-core/src/main/java/com/jme3/environment/LightProbeFactory2.java
  3. 5
      jme3-core/src/main/java/com/jme3/environment/baker/EnvBaker.java
  4. 8
      jme3-core/src/main/java/com/jme3/environment/baker/GenericEnvBaker.java
  5. 40
      jme3-examples/src/main/java/jme3test/light/pbr/TestPBRSimple.java

@ -0,0 +1,104 @@
package com.jme3.environment;
import java.util.function.Function;
import java.util.function.Predicate;
import com.jme3.asset.AssetManager;
import com.jme3.environment.baker.IBLGLEnvBakerLight;
import com.jme3.light.LightProbe;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.texture.Image.Format;
/**
* SmartLightProbe
*/
public class EnvironmentProbeControl extends LightProbe implements Control {
RenderManager renderManager;
AssetManager assetManager;
int envMapSize;
Spatial spatial;
boolean BAKE_NEEDED=true;
Function<Geometry,Boolean> filter=(s)->{
return s.getUserData("tags.env")!=null;
};
public static void tag(Spatial s){
if(s instanceof Node){
Node n=(Node)s;
for(Spatial sx:n.getChildren()){
tag(sx);
}
}else if(s instanceof Geometry){
s.setUserData("tags.env", true);
}
}
public EnvironmentProbeControl(RenderManager rm,AssetManager am, int size){
renderManager=rm;
assetManager=am;
envMapSize=size;
}
@Override
public Control cloneForSpatial(Spatial spatial) {
return null;
}
@Override
public void setSpatial(Spatial spatial) {
spatial.addLight(this);
this.spatial=spatial;
}
@Override
public void update(float tpf) {
}
@Override
public void render(RenderManager rm, ViewPort vp) {
if(BAKE_NEEDED){
BAKE_NEEDED=false;
rebakeNow();
}
}
public void rebake(){
BAKE_NEEDED=true;
}
void rebakeNow() {
System.out.println("BAKE");
IBLGLEnvBakerLight baker = new IBLGLEnvBakerLight(renderManager, assetManager, Format.RGB16F, Format.Depth,
envMapSize, envMapSize);
baker.bakeEnvironment(spatial, Vector3f.ZERO, 0.001f, 1000f,filter);
baker.bakeSpecularIBL();
baker.bakeSphericalHarmonicsCoefficients();
// probe.setPosition(Vector3f.ZERO);
setPrefilteredMap(baker.getSpecularIBL());
setNbMipMaps(getPrefilteredEnvMap().getImage().getMipMapSizes().length);
setShCoeffs(baker.getSphericalHarmonicsCoefficients());
setPosition(Vector3f.ZERO);
setReady(true);
baker.clean();
}
}

@ -51,7 +51,7 @@ public class LightProbeFactory2 {
am, Format.RGB16F, Format.Depth, am, Format.RGB16F, Format.Depth,
size, size); size, size);
baker.bakeEnvironment(scene,pos, frustumNear,frustumFar); baker.bakeEnvironment(scene,pos, frustumNear,frustumFar,null);
baker.bakeSpecularIBL(); baker.bakeSpecularIBL();
baker.bakeSphericalHarmonicsCoefficients(); baker.bakeSphericalHarmonicsCoefficients();
@ -72,7 +72,6 @@ public class LightProbeFactory2 {
/** /**
* For debuging porpose only * For debuging porpose only
* Will return a Node meant to be added to a GUI presenting the 2 cube maps in a cross pattern with all the mip maps. * Will return a Node meant to be added to a GUI presenting the 2 cube maps in a cross pattern with all the mip maps.

@ -1,6 +1,9 @@
package com.jme3.environment.baker; package com.jme3.environment.baker;
import java.util.function.Function;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.texture.TextureCubeMap; import com.jme3.texture.TextureCubeMap;
@ -10,7 +13,7 @@ import com.jme3.texture.TextureCubeMap;
* @author Riccardo Balbo * @author Riccardo Balbo
*/ */
public interface EnvBaker { public interface EnvBaker {
public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar); public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar,Function<Geometry,Boolean> filter);
public TextureCubeMap getEnvMap(); public TextureCubeMap getEnvMap();
public void clean(); public void clean();
} }

@ -4,6 +4,7 @@ import java.io.FileOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.function.Function;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.environment.baker.EnvBaker; import com.jme3.environment.baker.EnvBaker;
@ -14,6 +15,7 @@ import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager; import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.texture.FrameBuffer; import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
@ -117,7 +119,7 @@ public abstract class GenericEnvBaker implements EnvBaker{
@Override @Override
public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar) { public void bakeEnvironment(Spatial scene, Vector3f position, float frustumNear, float frustumFar,Function<Geometry,Boolean> filter) {
FrameBuffer envbaker=new FrameBuffer(env.getImage().getWidth(),env.getImage().getHeight(),1); FrameBuffer envbaker=new FrameBuffer(env.getImage().getWidth(),env.getImage().getHeight(),1);
envbaker.setDepthTarget(FrameBuffer.newTarget(depthFormat)); envbaker.setDepthTarget(FrameBuffer.newTarget(depthFormat));
envbaker.setSrgb(false); envbaker.setSrgb(false);
@ -139,7 +141,11 @@ public abstract class GenericEnvBaker implements EnvBaker{
scene.updateModelBound(); scene.updateModelBound();
scene.updateGeometricState(); scene.updateGeometricState();
Function<Geometry,Boolean> ofilter= renderManager.getRenderFilter();
renderManager.setRenderFilter(filter);
renderManager.renderViewPort(viewPort,0.16f); renderManager.renderViewPort(viewPort,0.16f);
renderManager.setRenderFilter(ofilter);
if(copyToRam){ if(copyToRam){
ByteBuffer face=BufferUtils.createByteBuffer( ByteBuffer face=BufferUtils.createByteBuffer(

@ -0,0 +1,40 @@
package jme3test.light.pbr;
import com.jme3.app.SimpleApplication;
import com.jme3.environment.EnvironmentProbeControl;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.util.SkyFactory;
import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
/**
* TestPBRSimple
*/
public class TestPBRSimple extends SimpleApplication{
public static void main(String[] args) {
new TestPBRSimple().start();
}
@Override
public void simpleInitApp() {
Geometry model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o");
MikktspaceTangentGenerator.generate(model);
Material pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m");
model.setMaterial(pbrMat);
rootNode.attachChild(model);
EnvironmentProbeControl envProbe=new EnvironmentProbeControl(renderManager,assetManager,256);
rootNode.addControl(envProbe);
Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
rootNode.attachChild(sky);
EnvironmentProbeControl.tag(sky);
}
}
Loading…
Cancel
Save