Suggestion, screen blendmode for bloom filter

It would be nice if one could specify blend mode as screen for bloom and glow effects :slight_smile: This blendmode will create a much softer glow than add which is used now.

mhh true…

We could use defines.

But you can do much better that suggesting :D, i know what you are capable of :wink:

sure, I can submit a patch :stuck_out_tongue: Can one trigger a define without passing a uniform to the shader? @nehon

Well you have to pass a parameter one way or an other…

you can do things like that



materialParameters {

Boolean useScreenBlending

}



defines {

USE_SCREEN_BLENDING useScreenBlending

}





The default would be additive like it’s done now, but is screen blending is set to true, it would be…screen blended :stuck_out_tongue:



This is ok if we have only 2 blend modes…

Yeah, but that will pass a unused Boolean as a uniform. Just trigger a define would be perfect in this case… but I will do as you suggest :slight_smile:

I agree having many more would make it harder to maintain, but I’m not against choices and options! :smiley: Never.

1 Like

No, it’s just a material parameter, if you don’t define it as a uniform in the shader it’s never passed to the shader.

Ahh, did not know that!

@nehon

only tested the GLSL100 version. Indention might be a bit off…

[patch]

Index: test/jme3test/post/BloomUI.java

===================================================================

— test/jme3test/post/BloomUI.java (revision 9294)

+++ test/jme3test/post/BloomUI.java (working copy)

@@ -33,6 +33,7 @@



import com.jme3.input.InputManager;

import com.jme3.input.KeyInput;

+import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.AnalogListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.post.filters.BloomFilter;

@@ -50,6 +51,7 @@

System.out.println("-- exposure Power : press U to increase, J to decrease");

System.out.println("-- exposure CutOff : press I to increase, K to decrease");

System.out.println("-- bloom Intensity : press O to increase, P to decrease");

  •    System.out.println(&quot;-- bloom blend mode : press T to toggle screen blend mode&quot;);<br />
    

System.out.println("


");

inputManager.addMapping("blurScaleUp", new KeyTrigger(KeyInput.KEY_Y));
@@ -60,6 +62,7 @@
inputManager.addMapping("exposureCutOffDown", new KeyTrigger(KeyInput.KEY_K));
inputManager.addMapping("bloomIntensityUp", new KeyTrigger(KeyInput.KEY_O));
inputManager.addMapping("bloomIntensityDown", new KeyTrigger(KeyInput.KEY_L));
+ inputManager.addMapping("bloomBlendMode", new KeyTrigger(KeyInput.KEY_T));


AnalogListener anl = new AnalogListener() {
@@ -104,6 +107,16 @@

inputManager.addListener(anl, "blurScaleUp", "blurScaleDown", "exposurePowerUp", "exposurePowerDown",
"exposureCutOffUp", "exposureCutOffDown", "bloomIntensityUp", "bloomIntensityDown");
+ inputManager.addListener(new ActionListener(){
+ boolean screenBlendMode = false;
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if(isPressed){
+ screenBlendMode = !screenBlendMode;
+ filter.setScreenBlendMode(screenBlendMode);
+ System.out.println("blend mode set to : " + (screenBlendMode ? "screen" : "additive"));
+ }
+ }
+ }, "bloomBlendMode");

}
}
Index: test/jme3test/post/TestBloom.java
===================================================================
--- test/jme3test/post/TestBloom.java (revision 9294)
+++ test/jme3test/post/TestBloom.java (working copy)
@@ -28,7 +28,7 @@
* 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;

Index: core-effects/Common/MatDefs/Post/bloomFinal.frag
===================================================================
--- core-effects/Common/MatDefs/Post/bloomFinal.frag (revision 9294)
+++ core-effects/Common/MatDefs/Post/bloomFinal.frag (working copy)
@@ -7,6 +7,10 @@
void main(){
vec4 colorRes = texture2D(m_Texture, texCoord);
vec4 bloom = texture2D(m_BloomTex, texCoord);
+ #ifdef SCREEN_MODE
+ gl_FragColor = 1.0 - ((1.0 - bloom * m_BloomIntensity)*(1.0 - colorRes));
+ #else
gl_FragColor = bloom * m_BloomIntensity + colorRes;
+ #endif
}

Index: core-effects/Common/MatDefs/Post/bloomFinal15.frag
===================================================================
--- core-effects/Common/MatDefs/Post/bloomFinal15.frag (revision 9294)
+++ core-effects/Common/MatDefs/Post/bloomFinal15.frag (working copy)
@@ -10,6 +10,10 @@
void main(){
vec4 colorRes = getColor(m_Texture,texCoord);
vec4 bloom = texture2D(m_BloomTex, texCoord);
- gl_FragColor = bloom * m_BloomIntensity + colorRes;
+ #ifdef SCREEN_MODE
+ gl_FragColor = 1.0 - ((1.0 - bloom * m_BloomIntensity)*(1.0 - colorRes));
+ #else
+ gl_FragColor = bloom * m_BloomIntensity + colorRes;
+ #endif
}

Index: core-effects/Common/MatDefs/Post/BloomFinal.j3md
===================================================================
--- core-effects/Common/MatDefs/Post/BloomFinal.j3md (revision 9294)
+++ core-effects/Common/MatDefs/Post/BloomFinal.j3md (working copy)
@@ -5,6 +5,7 @@
Texture2D Texture
Texture2D BloomTex
Float BloomIntensity
+ Boolean ScreenMode
}

Technique {
@@ -17,6 +18,7 @@

Defines {
RESOLVE_MS : NumSamples
+ SCREEN_MODE : ScreenMode
}
}

@@ -27,6 +29,10 @@
WorldParameters {
WorldViewProjectionMatrix
}
+
+ Defines{
+ SCREEN_MODE : ScreenMode
+ }
}


Index: core-effects/com/jme3/post/filters/BloomFilter.java
===================================================================
--- core-effects/com/jme3/post/filters/BloomFilter.java (revision 9294)
+++ core-effects/com/jme3/post/filters/BloomFilter.java (working copy)
@@ -90,7 +90,8 @@
private Material vBlurMat;
private Material hBlurMat;
private int screenWidth;
- private int screenHeight;
+ private int screenHeight;
+ private boolean screenBlendMode = false;

/**
* Creates a Bloom filter
@@ -182,6 +183,7 @@
@Override
protected Material getMaterial() {
material.setFloat("BloomIntensity", bloomIntensity);
+ material.setBoolean("ScreenMode", screenBlendMode);
return material;
}

@@ -282,6 +284,24 @@
public void setDownSamplingFactor(float downSamplingFactor) {
this.downSamplingFactor = downSamplingFactor;
}
+
+ /**
+ * Change the default additive blend mode to screen. Screen makes the glowing softer.
+ * @param screenBlendMode
+ */
+
+ public void setScreenBlendMode(boolean screenBlendMode){
+ this.screenBlendMode = screenBlendMode;
+ }
+
+ /**
+ * returns true if the blend mode is screen.
+ * @return
+ */
+
+ public boolean isScreenBlendMode(){
+ return screenBlendMode;
+ }

@Override
public void write(JmeExporter ex) throws IOException {
@@ -293,6 +313,7 @@
oc.write(exposureCutOff, "exposureCutOff", 0.0f);
oc.write(bloomIntensity, "bloomIntensity", 2.0f);
oc.write(downSamplingFactor, "downSamplingFactor", 1);
+ oc.write(screenBlendMode, "screenBlendMode", screenBlendMode);
}

@Override
@@ -305,5 +326,6 @@
exposureCutOff = ic.readFloat("exposureCutOff", 0.0f);
bloomIntensity = ic.readFloat("bloomIntensity", 2.0f);
downSamplingFactor = ic.readFloat("downSamplingFactor", 1);
+ screenBlendMode = ic.readBoolean("screenBlendMode", screenBlendMode);
}
}

[/patch]
Probably the blendmode should be an enum, but now it's not..
3 Likes

Can we see a screenshot of original bloom vs. the blended bloom?

@Momoko_Fan



In this setup GlowMode is set to scene and the bloom filter is applied after the fog filter.



Original scene:

http://i.imgur.com/ZIj9w.jpg



Additive blend mode, jME default

http://i.imgur.com/2b1Nv.jpg



Screen blend mode

http://i.imgur.com/yZBj0.jpg

3 Likes

Awesome results there. :smiley:

wow…gorgeous!

I’ll add this to the bloomFilter, thanks a lot for this contribution

Yeah, a small change can give great results :slight_smile:



I have several other ideas on my list waiting to be implemented and shared, so stay tuned :stuck_out_tongue:

1 Like

wow! it has a feeling of HDR.