Barrel Distortion Lens

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

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
public class BarrelDistortionFilter extends Filter {
     public BarrelDistortionFilter() {

     protected Material getMaterial() {
         return material;

     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);
         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.

Christian Liesch

Software Developer

0 0 votes
Article Rating

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments