After the fisheye lens shader turned out to be too extreme for All Fucked Up I looked for other lens shaders and found barrel distortion shaders which makes a similar effect like a fisheye but less extreme. It just widens up the lens. Looks totally cool. I got the best and simplest shader for barrel distortion here on github. It’s in a different format than I need it for jMonkeyEngine but was quite simple to adapt it.
I always start with the part I need to embed the shader in the code and as I do not make anything fancy or parametrized it’s fairly straight forward
package ch.artificials.bubble.system.mvc.view.post.filter;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.post.Filter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
public class BarrelDistortionFilter extends Filter {
public BarrelDistortionFilter() {
super(BarrelDistortionFilter.class.getSimpleName());
}
@Override
protected Material getMaterial() {
return material;
}
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
material = new Material(manager, "MatDefs/Post/BarrelDistortion.j3md");
}
}
The referenced MatDefs/Post/BarrelDistortion.j3md holds the references to the shader code and also defines possible parameters which we want to hand over from code to the shader code.
MaterialDef Toon {
MaterialParameters {
Int NumSamples
Int NumSamplesDepth
Texture2D Texture
Color Color
}
Technique {
VertexShader GLSL100: MatDefs/Post/BarrelDistortion.vert
FragmentShader GLSL100: MatDefs/Post/BarrelDistortion.frag
WorldParameters {
}
Defines {
RESOLVE_MS : NumSamples
}
}
}
The vertex shader code is very simple and just hands over the tex coordinate and the position
import "Common/ShaderLib/GLSLCompat.glsllib"
attribute vec4 inPosition;
varying vec2 Vertex_UV;
attribute vec2 inTexCoord;
void main()
{
vec2 pos = inPosition.xy * 2.0 - 1.0;
gl_Position = vec4(pos, 0.0, 1.0);
Vertex_UV = inTexCoord;
}
The barrel distortion logic is in the fragment shader code and looks like this
import "Common/ShaderLib/GLSLCompat.glsllib"
import "Common/ShaderLib/MultiSample.glsllib"
uniform sampler2D tex0;
varying vec2 Vertex_UV;
uniform sampler2D Texture;
const float BARREL_DISTORTION = 0.25;
const float rescale = 1.0 - (0.25 * BARREL_DISTORTION);
void main()
{
vec2 tex0 = Vertex_UV;
vec2 texcoord = tex0 - vec2(0.5);
float rsq = texcoord.x * texcoord.x + texcoord.y * texcoord.y;
texcoord = texcoord + (texcoord * (BARREL_DISTORTION * rsq));
texcoord *= rescale;
if (abs(texcoord.x) > 0.5 || abs(texcoord.y) > 0.5)
gl_FragColor = vec4(0.0);
else
{
texcoord += vec2(0.5);
vec3 colour = texture2D(Texture, texcoord).rgb;
gl_FragColor = vec4(colour,1.0);
}
}
And the lens effect in action looks like this
I get a small commissions for purchases made through the following links, I only have books in this section which I bought myself and which I love. No bullshit.