Alpha to coverage and filters does not work well. It’s very weird.
This is an example with bloom, and it’s the same with fog and other stuff. When I run the bloom filter this happens:
- It works perfectly with MS disabled.
- It works perfectly with MS enabled (as far as I could tell, only tested to 4x).
- With atoc enabled it causes weird artifacts.
http://www.jamtlandoutdoors.se/images/dist/bloom_smear.png
The bloom areas looks fine as long as the camera has not moved, but when I move the camera the colors are smeared out. In the image I’m moving the camera down and to the right, slowly. Every bloomed object acts sort of like a particle emitter while in view.
I would be very grateful if someone with an NVIDIA card (and also someone with a new Radeon card) could try this test case. It looks like the frame buffers aren’t cleared properly. Just run the test, drag the camera around the sky for some time then go back to the teapot. If it fails there will be a bunch of garbage on the screen.
package jme3test.post;
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.debug.WireFrustum;
import com.jme3.scene.shape.Box;
import com.jme3.util.SkyFactory;
import org.lwjgl.opengl.ARBMultisample;
import static org.lwjgl.opengl.GL11.*;
public class TestBloom extends SimpleApplication {
float angle;
Spatial lightMdl;
Spatial teapot;
Geometry frustumMdl;
WireFrustum frustum;
boolean active=true;
FilterPostProcessor fpp;
public static void main(String[] args){
TestBloom app = new TestBloom();
app.start();
}
@Override
public void simpleInitApp() {
glEnable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
// put the camera in a bad position
cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f));
cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f));
//cam.setFrustumFar(1000);
Material mat = new Material(assetManager,“Common/MatDefs/Light/Lighting.j3md”);
mat.setFloat(“Shininess”, 15f);
mat.setBoolean(“UseMaterialColors”, true);
mat.setColor(“Ambient”, ColorRGBA.Yellow.mult(0.2f));
mat.setColor(“Diffuse”, ColorRGBA.Yellow.mult(0.2f));
mat.setColor(“Specular”, ColorRGBA.Yellow.mult(0.8f));
Material matSoil = new Material(assetManager,“Common/MatDefs/Light/Lighting.j3md”);
matSoil.setFloat(“Shininess”, 15f);
matSoil.setBoolean(“UseMaterialColors”, true);
matSoil.setColor(“Ambient”, ColorRGBA.Gray);
matSoil.setColor(“Diffuse”, ColorRGBA.Black);
matSoil.setColor(“Specular”, ColorRGBA.Gray);
teapot = assetManager.loadModel(“Models/Teapot/Teapot.obj”);
teapot.setLocalTranslation(0,0,10);
teapot.setMaterial(mat);
teapot.setShadowMode(ShadowMode.CastAndReceive);
teapot.setLocalScale(10.0f);
rootNode.attachChild(teapot);
Geometry soil=new Geometry(“soil”, new Box(new Vector3f(0, -13, 550), 800, 10, 700));
soil.setMaterial(matSoil);
soil.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(soil);
DirectionalLight light=new DirectionalLight();
light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
light.setColor(ColorRGBA.White.mult(1.5f));
rootNode.addLight(light);
// load sky
Spatial sky = SkyFactory.createSky(assetManager, “Textures/Sky/Bright/FullskiesBlueClear03.dds”, false);
sky.setCullHint(Spatial.CullHint.Never);
rootNode.attachChild(sky);
fpp=new FilterPostProcessor(assetManager);
// fpp.setNumSamples(4);
BloomFilter bloom=new BloomFilter();
bloom.setDownSamplingFactor(2);
bloom.setBlurScale(1.37f);
bloom.setExposurePower(3.30f);
bloom.setExposureCutOff(0.2f);
bloom.setBloomIntensity(2.45f);
BloomUI ui=new BloomUI(inputManager, bloom);
viewPort.addProcessor(fpp);
fpp.addFilter(bloom);
fpp.setNumSamples(4);
initInputs();
}
private void initInputs() {
inputManager.addMapping(“toggle”, new KeyTrigger(KeyInput.KEY_SPACE));
ActionListener acl = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals(“toggle”) && keyPressed) {
if(active){
active=false;
viewPort.removeProcessor(fpp);
}else{
active=true;
viewPort.addProcessor(fpp);
}
}
}
};
inputManager.addListener(acl, “toggle”);
}
}