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

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.

cli

Software Developer

0 0 votes
Article Rating

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

0 Comments
Inline Feedbacks
View all comments