This isn’t really plugin worthy, but thought I would post it for anyone who have a need for it:
It’s a simple post filter that renders a specified GeomtryList with a forced material and then does a depth check to blend back into the scene any portions of the geometries that are obstructed by other objects.
Here is a screen shot of what it does:
The code:
GhostImage.java
[java]
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.post.Filter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.GeometryList;
import com.jme3.renderer.queue.OpaqueComparator;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture2D;
/**
*
-
@author t0neg0d
*/
public class GhostImage extends Filter {
RenderManager rm;
AssetManager am;
ViewPort vp;
GeometryList geoms;
Pass ghosts;
Material ghostMat;
FrameBuffer ghostBuffer;public GhostImage(ViewPort vp) {
super(“GhostImage”);
OpaqueComparator comp = new OpaqueComparator();
comp.setCamera(vp.getCamera());
geoms = new GeometryList(comp);
}@Override
protected void postQueue(RenderQueue renderQueue) {
if (geoms.size() > 0) {
Renderer r = rm.getRenderer();
r.setFrameBuffer(ghostBuffer);
rm.getRenderer().clearBuffers(true, true, true);
rm.setForcedMaterial(ghostMat);
rm.renderGeometryList(geoms);
rm.setForcedMaterial(null);
r.setFrameBuffer(vp.getOutputFrameBuffer());
}
}@Override
protected boolean isRequiresDepthTexture() {
return true;
}@Override
protected boolean isRequiresSceneTexture() {
return true;
}@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
this.rm = renderManager;
this.am = manager;
this.vp = vp;ghostBuffer = new FrameBuffer(w,h,1); Texture2D ghostImage = new Texture2D(w,h,1,Format.ABGR8); Texture2D ghostDepth = new Texture2D(w,h,1,Format.Depth); ghostBuffer.setColorTexture(ghostImage); ghostBuffer.setDepthTexture(ghostDepth); ghostMat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); ghostMat.setColor("Color", ColorRGBA.Blue); material = new Material(manager, "MatDefs/GhostImage.j3md"); material.setTexture("GhostDepth", ghostDepth); material.setTexture("GhostImage", ghostImage);
}
@Override
protected Material getMaterial() {
return this.material;
}public void addToGeometryList(GeometryList geoms) {
for (int g = 0; g < geoms.size(); g++) {
boolean add = true;
for (int g2 = 0; g2 < this.geoms.size(); g2++) {
if (this.geoms.get(g2) == geoms.get(g)) {
add = false;
break;
}
}
if (add)
this.geoms.add(geoms.get(g));
}
}public GeometryList getGeometryList() {
return this.geoms;
}
}
[/java]
GhostImage.j3md
[java]
MaterialDef GhostImage {
MaterialParameters {
Int NumSamples
Int NumSamplesDepth
Texture2D DepthTexture
Texture2D Texture
Texture2D GhostImage
Texture2D GhostDepth
}
Technique {
VertexShader GLSL100: Common/MatDefs/Post/Post.vert
FragmentShader GLSL100: Shaders/GhostImage.frag
WorldParameters {
WorldViewProjectionMatrix
}
}
}
[/java]
GhostImage.frag
[java]
uniform sampler2D m_Texture;
uniform sampler2D m_DepthTexture;
uniform sampler2D m_GhostImage;
uniform sampler2D m_GhostDepth;
varying vec2 texCoord;
void main() {
float sceneDepth = texture2D(m_DepthTexture,texCoord).r;
float ghostDepth = texture2D(m_GhostDepth,texCoord).r;
vec4 scene = texture2D(m_Texture,texCoord);
if (ghostDepth <= sceneDepth || ghostDepth == 1.0)
gl_FragColor = scene;
else
gl_FragColor = mix(scene,texture2D(m_GhostImage,texCoord),0.25);
}
[/java]
Simple usage:
[java]
// Create filter instance
ghosts = new GhostImage(viewPort);
// Add to FilterPostProcessor
// Create GeometryList, add Geometries to it, set the filter’s current Geometry list
GeometryList ghostGeoms = new GeometryList(new OpaqueComparator());
ghostGeoms.add( someGeom );
ghostGeoms.add( someOtherGeom );
ghosts.addToGeometryList(ghostGeoms);
[/java]
You can swap out the GeometryList at any point during a frame update.
End of Line