But only if one of the filters requires it:
I used both waterfilter and fogfilter and enabled them but when I used filterPostProcessor.getDepthTexture(); it return null for depthTexture.getImage()
So if I burden you somehow can you give a working code when you have time, it’ll also benefit the future user
From where? Where did you call it? When did you call it?
…depth texture clearly works in a filter post processor else water wouldn’t work, fog wouldn’t work, etc…
If you expect the depth texture to be available “at any random time of your choosing” then you might be disappointed.
You might also try looking in the JME examples as I recall that there are a few of them that render various depth buffers in little debug displays.
fogFilter = new FogFilter() {
@Override
protected void setDepthTexture(Texture depthTexture) {
super.setDepthTexture(depthTexture);
// Grab depth texture and use it for good!
System.out.println("depthTexture=" + depthTexture);
}
};
Not the best solution of course!
I tried your code it produced null images for both renderedTextured and depthTextured
FogFilter fogFilter = new FogFilter() {
protected void setDepthTexture(Texture depthTexture) {
super.setDepthTexture(Main.this.depthTexture);
Main.this.depthTexture = (Texture2D) depthTexture;
}
protected boolean isRequiresDepthTexture() {
return true;
}
@Override
protected void setRenderedTexture(Texture2D renderedTexture) {
super.setRenderedTexture(renderedTexture);
Main.this.renderedTexture = renderedTexture;
}
};
fogFilter.setEnabled(true);
FilterPostProcessor filterPostProcessor = new FilterPostProcessor(assetManager);
filterPostProcessor.addFilter(fogFilter);
viewPort.addProcessor(filterPostProcessor);
And I implemented the filter class directly with this code with the same result for both textures
Filter filter = new Filter() {
private Pass reflectionPass;
protected Spatial reflectionScene;
protected Spatial rootScene = rootNode;
protected ViewPort reflectionView;
private Camera reflectionCam;
private int reflectionMapSize = 512;
private Material material;
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
rootScene = vp.getScenes().get(0);
if (reflectionScene == null) {
reflectionScene = rootScene;
}
reflectionPass = new Pass();
reflectionPass.init(renderManager.getRenderer(), reflectionMapSize, reflectionMapSize, Format.RGBA8, Format.Depth,1,true);
reflectionCam = new Camera(reflectionMapSize, reflectionMapSize);
reflectionView = new ViewPort("reflectionView", reflectionCam);
reflectionView.setClearFlags(true, true, true);
reflectionView.attachScene(reflectionScene);
reflectionView.setOutputFrameBuffer(reflectionPass.getRenderFrameBuffer());
renderedTexture = (Texture2D) reflectionPass.getRenderFrameBuffer().getColorTarget().getTexture();
material = new Material(manager, "Common/MatDefs/Water/Water.j3md");
}
@Override
protected Material getMaterial() {
return material;
}
@Override
protected boolean isRequiresDepthTexture() {
return true;
}
@Override
public void setDepthTexture(Texture depthTexture) {
super.setDepthTexture(depthTexture);
Main.this.depthTexture = (Texture2D) depthTexture;
}
@Override
protected void setRenderedTexture(Texture2D renderedTexture) {
super.setRenderedTexture(renderedTexture);
Main.this.renderedTexture = renderedTexture;
}
};
filter.setEnabled(true);
FilterPostProcessor filterPostProcessor = new FilterPostProcessor(assetManager);
filterPostProcessor.addFilter(filter);
viewPort.addProcessor(filterPostProcessor);
However with direct code I can produce renderedTexture but not depthTexture where am I doing wrong?
int width = getContext().getSettings().getWidth();
int height = getContext().getSettings().getHeight();
Camera reflectionCam = new Camera(width, height);
reflectionCam.setFrustumPerspective(getCamera().getFov(), getCamera().getAspect(), 0.01f, 1000);
reflectionCam.setLocation(new Vector3f(0, 0, -6.f));
ViewPort reflectionView = renderManager.createPreView("reflectionView", getCamera());
reflectionView.setEnabled(true);
reflectionView.setClearFlags(true, true, true);
reflectionView.attachScene(getRootNode());
renderFrameBuffer = new FrameBuffer(width, height, 1);
reflectionView.setOutputFrameBuffer(renderFrameBuffer);
depthTexture = new Texture2D(width, height, Format.Depth);
renderedTexture = new Texture2D(width, height, Format.RGBA8);
renderFrameBuffer.setDepthTarget(FrameBufferTarget.newTarget(depthTexture));
renderFrameBuffer.addColorTarget(FrameBufferTarget.newTarget(renderedTexture));
reflectionView.setOutputFrameBuffer(renderFrameBuffer);
Add a System.out.println(depthTexture)
inside setDepthTexture
method just like I did and we will see if it is null or not:
fogFilter = new FogFilter() {
@Override
protected void setDepthTexture(Texture depthTexture) {
super.setDepthTexture(depthTexture);
System.out.println("depthTexture=" + depthTexture);
}
};
I did this inside setDepthTexture()
Main.this.depthTexture = (Texture2D) depthTexture;
Please do this and let me know what it prints in the console.
It produces nothing at all
Update
I set one in setRenderedTexture
it also produces nothing as well
Please show the complete code.
I tested and it prints this in the console in my case
depthTexture=Texture2D[name=null, image=Image[size=832x624, format=Depth]]
Ok my bad
for depthTextured
depthTextureTexture2D[name=null, image=Image[size=640x480, format=Depth]]
but none for setRenderedTexture
So it is not null you just needed to wait for Filter to be initialized properly before you can use Main.this.renderedTexture
.
in another word you can not access it from simpleInitApp
because the filter is not yet initialized.
So where and when and how I can access it
do I need to execute the code in update or render methods after period of time?
You can check it in the update loop until it becomes available then use it. I have never used it before so I do not know if you also need to consider anything else.
I made a CustomFogFilter
public class CustomFogFilter extends FogFilter {
private Texture2D renderedTexture;
private Texture2D depthTexture;
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
super.initFilter(manager, renderManager, vp, w, h);
renderedTexture = (Texture2D) this.defaultPass.getRenderFrameBuffer().getColorTarget().getTexture();
}
@Override
protected Material getMaterial() {
return material;
}
@Override
protected boolean isRequiresDepthTexture() {
return true;
}
@Override
protected boolean isRequiresSceneTexture() {
return true;
}
@Override
public void setDepthTexture(Texture depthTexture) {
super.setDepthTexture(depthTexture);
System.out.println("depthTexture "+depthTexture);
this.depthTexture = (Texture2D) depthTexture;
}
@Override
protected void setRenderedTexture(Texture2D renderedTexture) {
super.setRenderedTexture(renderedTexture);
this.renderedTexture = renderedTexture;
System.out.println("renderedTexture "+renderedTexture);
}
public Texture2D getDepthTexture() {
return depthTexture;
}
public Texture2D getRenderedTexture() {
return renderedTexture;
}
And I made this code in Update method
loops++;
if(loops>100) {
if(filter.getDepthTexture().getImage()!=null) {
picture2.setTexture(assetManager, filter.getDepthTexture(), false);
}
if(filter.getRenderedTexture().getImage()!=null) {
picture1.setTexture(assetManager, filter.getRenderedTexture(), false);
}
}
There is no Null error any more but empty images
Some pitfalls when using depth textures:
Make sure it is really not working. Only because it is all white does not imply that. It is expected to be white not very far away from the camera.
You cannot simply copy the image to another object and use that at some random time. It will still refer to the same image you are rendering/clearing
Make sure your do not render a full screen quad with depth write enabled as long as you have bound the depth texture.
The gl specs do not allow reading and writing to the same texture at any given time. Result is not defined and may be correct or wrong or partially wrong depending on the driver/gpu.
Thank you for you response
Doesn’t the depth texture updated frequently
There is no full screen quad (I can post the full code if you want)
How could I obtain depth texture then? there is no working example anywhere!
What is it that you are actually tying to do? ie: what do you need the depth texture for?
I want to use it in my shader but I want to ensure it is correctly produced by visualizing it
Certainly what you want to do is possible. I don’t have time to find the JME example that renders depth textures in the HUD for you but they exist.
In the mean time, it seems like it would be a million times easier just to debug the values in your shader. Render the depth instead of rendering your normal color “just to see”, etc… It’s also more reliable because it’s “ground truth” where as a secondary render is very likely to be one frame behind depending on how you hook it up.