Fixed the DepthOfFieldFilter to properly get the near/far distance from JME
instead of having it hard-coded. Previous behavior caused focus to go all out of whack if you ever changed the near/far plane (and even the default hard-coded value was not the same as JME's default camera setup.) While I was here, I made the unfocus threshold configurable and added a debug toggle that will turn the 'unfocus' amount into grayscale color for better visualizing where unfocusing is happening.
This commit is contained in:
parent
b62fbdbf84
commit
81667f8f45
@ -54,11 +54,14 @@ public class DepthOfFieldFilter extends Filter {
|
||||
private float focusDistance = 50f;
|
||||
private float focusRange = 10f;
|
||||
private float blurScale = 1f;
|
||||
private float blurThreshold = 0.2f;
|
||||
// These values are set internally based on the
|
||||
// viewport size.
|
||||
private float xScale;
|
||||
private float yScale;
|
||||
|
||||
private boolean debugUnfocus;
|
||||
|
||||
/**
|
||||
* Creates a DepthOfField filter
|
||||
*/
|
||||
@ -83,7 +86,8 @@ public class DepthOfFieldFilter extends Filter {
|
||||
material = new Material(assets, "Common/MatDefs/Post/DepthOfField.j3md");
|
||||
material.setFloat("FocusDistance", focusDistance);
|
||||
material.setFloat("FocusRange", focusRange);
|
||||
|
||||
material.setFloat("BlurThreshold", blurThreshold);
|
||||
material.setBoolean("DebugUnfocus", debugUnfocus);
|
||||
|
||||
xScale = 1.0f / w;
|
||||
yScale = 1.0f / h;
|
||||
@ -161,13 +165,62 @@ public class DepthOfFieldFilter extends Filter {
|
||||
return blurScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum blur factor before the convolution filter is
|
||||
* calculated. The default is 0.2 which means if the "unfocus"
|
||||
* amount is less than 0.2 (where 0 is no blur and 1.0 is full blurScale)
|
||||
* then no blur will be applied at all. Depending on the GPU implementation,
|
||||
* this may be an optimization since it uses branching to skip the expensive
|
||||
* convolution filter.
|
||||
*
|
||||
* <p>In scenes where the focus distance is close (like 0) and the focus range
|
||||
* is relatively large, this threshold will remove some subtlety in
|
||||
* the near-camera blurring and should be set smaller than the default
|
||||
* or to 0 to disable completely. Sometimes that cut-off is desired if
|
||||
* mid-to-far field unfocusing is all that is desired.</p>
|
||||
*/
|
||||
public void setBlurThreshold( float f ) {
|
||||
this.blurThreshold = f;
|
||||
if (material != null) {
|
||||
material.setFloat("BlurThreshold", blurThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the blur threshold.
|
||||
* @return
|
||||
*/
|
||||
public float getBlurThreshold() {
|
||||
return blurThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on/off debugging of the 'unfocus' value that is used to
|
||||
* mix the convolution filter. When this is on, the 'unfocus' value
|
||||
* is rendered as gray scale. This can be used to more easily visualize
|
||||
* where in your view the focus is centered and how steep the gradient/cutoff
|
||||
* is, etc..
|
||||
*/
|
||||
public void setDebugUnfocus( boolean b ) {
|
||||
this.debugUnfocus = b;
|
||||
if( material != null ) {
|
||||
material.setBoolean("DebugUnfocus", debugUnfocus);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getDebugUnfocus() {
|
||||
return debugUnfocus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(blurScale, "blurScale", 1f);
|
||||
oc.write(blurScale, "blurThreshold", 0.2f);
|
||||
oc.write(focusDistance, "focusDistance", 50f);
|
||||
oc.write(focusRange, "focusRange", 10f);
|
||||
oc.write(debugUnfocus, "debugUnfocus", false); // strange to write this I guess
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,7 +228,9 @@ public class DepthOfFieldFilter extends Filter {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
blurScale = ic.readFloat("blurScale", 1f);
|
||||
blurThreshold = ic.readFloat("blurThreshold", 0.2f);
|
||||
focusDistance = ic.readFloat("focusDistance", 50f);
|
||||
focusRange = ic.readFloat("focusRange", 10f);
|
||||
debugUnfocus = ic.readBoolean("debugUnfocus", false);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ uniform float m_FocusDistance;
|
||||
uniform float m_XScale;
|
||||
uniform float m_YScale;
|
||||
|
||||
vec2 m_NearFar = vec2( 0.1, 1000.0 );
|
||||
uniform vec2 g_FrustumNearFar;
|
||||
|
||||
void main() {
|
||||
|
||||
@ -31,8 +31,8 @@ void main() {
|
||||
// z * (zb - a) = b
|
||||
// z = b / (zb - a)
|
||||
//
|
||||
float a = m_NearFar.y / (m_NearFar.y - m_NearFar.x);
|
||||
float b = m_NearFar.y * m_NearFar.x / (m_NearFar.x - m_NearFar.y);
|
||||
float a = g_FrustumNearFar.y / (g_FrustumNearFar.y - g_FrustumNearFar.x);
|
||||
float b = g_FrustumNearFar.y * g_FrustumNearFar.x / (g_FrustumNearFar.x - g_FrustumNearFar.y);
|
||||
float z = b / (zBuffer - a);
|
||||
|
||||
// Above could be the same for any depth-based filter
|
||||
@ -42,7 +42,7 @@ void main() {
|
||||
// at +/- m_FocusRange to either side of that.
|
||||
float unfocus = min( 1.0, abs( z - m_FocusDistance ) / m_FocusRange );
|
||||
|
||||
if( unfocus < 0.2 ) {
|
||||
if( unfocus < BLUR_THRESHOLD ) {
|
||||
// If we are mostly in focus then don't bother with the
|
||||
// convolution filter
|
||||
gl_FragColor = texVal;
|
||||
@ -86,7 +86,11 @@ void main() {
|
||||
|
||||
gl_FragColor = mix( texVal, sum, unfocus );
|
||||
|
||||
// I used this for debugging the range
|
||||
// gl_FragColor.r = unfocus;
|
||||
#ifdef DEBUG_UNFOCUS
|
||||
// Used for debugging the range or user settings
|
||||
gl_FragColor.r = unfocus;
|
||||
gl_FragColor.g = unfocus;
|
||||
gl_FragColor.b = unfocus;
|
||||
#endif
|
||||
}
|
||||
}
|
@ -9,6 +9,8 @@ MaterialDef Depth Of Field {
|
||||
Float FocusDistance;
|
||||
Float XScale;
|
||||
Float YScale;
|
||||
Float BlurThreshold : 0.2;
|
||||
Boolean DebugUnfocus : false;
|
||||
}
|
||||
|
||||
Technique {
|
||||
@ -16,11 +18,14 @@ MaterialDef Depth Of Field {
|
||||
FragmentShader GLSL150 GLSL100: Common/MatDefs/Post/DepthOfField.frag
|
||||
|
||||
WorldParameters {
|
||||
FrustumNearFar
|
||||
}
|
||||
|
||||
Defines {
|
||||
RESOLVE_MS : NumSamples
|
||||
RESOLVE_DEPTH_MS : NumSamplesDepth
|
||||
BLUR_THRESHOLD : BlurThreshold
|
||||
DEBUG_UNFOCUS : DebugUnfocus
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user