diff --git a/engine/src/core-effects/Common/MatDefs/Post/Compose.frag b/engine/src/core-effects/Common/MatDefs/Post/Compose.frag new file mode 100644 index 000000000..24eb80c22 --- /dev/null +++ b/engine/src/core-effects/Common/MatDefs/Post/Compose.frag @@ -0,0 +1,10 @@ +uniform sampler2D m_Texture; +uniform sampler2D m_CompositeTexture; +varying vec2 texCoord; + +void main() { + vec4 texVal = texture2D(m_Texture, texCoord); + vec4 compositeVal = texture2D(m_CompositeTexture, texCoord); + gl_FragColor = mix(compositeVal,texVal,texVal.a); +} + diff --git a/engine/src/core-effects/Common/MatDefs/Post/Compose.j3md b/engine/src/core-effects/Common/MatDefs/Post/Compose.j3md new file mode 100644 index 000000000..67cbc70b6 --- /dev/null +++ b/engine/src/core-effects/Common/MatDefs/Post/Compose.j3md @@ -0,0 +1,33 @@ +MaterialDef Default GUI { + + MaterialParameters { + Int NumSamples + Int NumSamplesDepth + Texture2D Texture + Texture2D CompositeTexture + } + + Technique { + VertexShader GLSL150: Common/MatDefs/Post/Post15.vert + FragmentShader GLSL150: Common/MatDefs/Post/Compose15.frag + + WorldParameters { + WorldViewProjectionMatrix + } + + Defines { + RESOLVE_MS : NumSamples + } + + } + + Technique { + VertexShader GLSL100: Common/MatDefs/Post/Post.vert + FragmentShader GLSL100: Common/MatDefs/Post/Compose.frag + + WorldParameters { + WorldViewProjectionMatrix + } + + } +} \ No newline at end of file diff --git a/engine/src/core-effects/Common/MatDefs/Post/Compose15.frag b/engine/src/core-effects/Common/MatDefs/Post/Compose15.frag new file mode 100644 index 000000000..3a4032f91 --- /dev/null +++ b/engine/src/core-effects/Common/MatDefs/Post/Compose15.frag @@ -0,0 +1,14 @@ +#import "Common/ShaderLib/MultiSample.glsllib" + +uniform COLORTEXTURE m_Texture; +uniform COLORTEXTURE m_CompositeTexture; +in vec2 texCoord; + +out vec4 finalColor; + +void main() { + vec4 texVal = getColor(m_Texture, texCoord); + vec4 compositeVal = getColor(m_CompositeTexture, texCoord); + finalColor = mix(compositeVal,texVal,texVal.a); +} + diff --git a/engine/src/core-effects/com/jme3/post/filters/ComposeFilter.java b/engine/src/core-effects/com/jme3/post/filters/ComposeFilter.java new file mode 100644 index 000000000..2aff1b174 --- /dev/null +++ b/engine/src/core-effects/com/jme3/post/filters/ComposeFilter.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.post.filters; + +import com.jme3.asset.AssetManager; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.material.Material; +import com.jme3.post.Filter; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.texture.Texture2D; +import java.io.IOException; + +/** + * This filter compose a texture with the viewport texture. This is used to + * compose post processed texture from another viewport. + * + * the compositing is done using the alpha value of the viewportTexture : + * mix(compositeTextureColor, viewPortColor, viewportColor.alpha); + * + * It's important for a good result that the viewport clear color alpha be 0. + * + * @author Rémy Bouquet aka Nehon + */ +public class ComposeFilter extends Filter { + + private Texture2D compositeTexture; + + /** + * creates a ComposeFilter + */ + public ComposeFilter() { + super("Compose Filter"); + } + + /** + * creates a ComposeFilter with the given texture + * + * @param color + */ + public ComposeFilter(Texture2D compositeTexture) { + this(); + this.compositeTexture = compositeTexture; + } + + @Override + protected Material getMaterial() { + + material.setTexture("CompositeTexture", compositeTexture); + return material; + } + + /** + * + * @return the compositeTexture + */ + public Texture2D getCompositeTexture() { + return compositeTexture; + } + + /** + * sets the compositeTexture + * + * @param compositeTexture + */ + public void setCompositeTexture(Texture2D compositeTexture) { + this.compositeTexture = compositeTexture; + } + + @Override + protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) { + material = new Material(manager, "Common/MatDefs/Post/Compose.j3md"); + } + + @Override + public void write(JmeExporter ex) throws IOException { + super.write(ex); + OutputCapsule oc = ex.getCapsule(this); + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule ic = im.getCapsule(this); + } +} diff --git a/engine/src/test/jme3test/post/TestPostFiltersCompositing.java b/engine/src/test/jme3test/post/TestPostFiltersCompositing.java new file mode 100644 index 000000000..f05276a81 --- /dev/null +++ b/engine/src/test/jme3test/post/TestPostFiltersCompositing.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package jme3test.post; + +import com.jme3.app.SimpleApplication; +import com.jme3.asset.plugins.ZipLocator; +import com.jme3.light.DirectionalLight; +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.post.filters.ColorOverlayFilter; +import com.jme3.post.filters.ComposeFilter; +import com.jme3.scene.Spatial; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image; +import com.jme3.texture.Texture2D; +import com.jme3.util.SkyFactory; + +/** + * This test showcases the possibility to compose the post filtered outputs of several viewports. + * The usual use case is when you want to apply some post process to the main viewport and then other post process to the gui viewport + * @author Nehon + */ +public class TestPostFiltersCompositing extends SimpleApplication { + + public static void main(String[] args) { + TestPostFiltersCompositing app = new TestPostFiltersCompositing(); + app.start(); + } + + public void simpleInitApp() { + this.flyCam.setMoveSpeed(10); + cam.setLocation(new Vector3f(6.0344796f, 1.5054002f, 55.572033f)); + cam.setRotation(new Quaternion(0.0016069f, 0.9810479f, -0.008143323f, 0.19358753f)); + + makeScene(); + + //Creating the main view port post processor + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + fpp.addFilter(new ColorOverlayFilter(ColorRGBA.Blue)); + viewPort.addProcessor(fpp); + + //creating a frame buffer for the mainviewport + FrameBuffer mainVPFrameBuffer = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + Texture2D mainVPTexture = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + mainVPFrameBuffer.addColorTexture(mainVPTexture); + mainVPFrameBuffer.setDepthBuffer(Image.Format.Depth); + viewPort.setOutputFrameBuffer(mainVPFrameBuffer); + + //creating the post processor for the gui viewport + final FilterPostProcessor guifpp = new FilterPostProcessor(assetManager); + guifpp.addFilter(new ColorOverlayFilter(ColorRGBA.Red)); + //this will compose the main viewport texture with the guiviewport back buffer. + //Note that you can swich the order of the filters so that guiviewport filters are applied or not to the main viewport texture + guifpp.addFilter(new ComposeFilter(mainVPTexture)); + + guiViewPort.addProcessor(guifpp); + + //compositing is done my mixing texture depending on the alpha channel, + //it's important that the guiviewport clear color alpha value is set to 0 + guiViewPort.setBackgroundColor(new ColorRGBA(0, 0, 0, 0)); + + + } + + private void makeScene() { + // load sky + rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false)); + assetManager.registerLocator("wildhouse.zip", ZipLocator.class); + Spatial scene = assetManager.loadModel("main.scene"); + DirectionalLight sun = new DirectionalLight(); + sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f)); + sun.setColor(ColorRGBA.White.clone().multLocal(2)); + scene.addLight(sun); + rootNode.attachChild(scene); + } +}