Fisheye perspective

I wonder if somebody did ever a fisheye perspective and/or if there is something laying around which I could use? I searched the forum and I couldn’t find anything specific on this topic. I guess the standard camera can’t do this.

Standard rendering can’t do this because straight edges are no longer straight.

If you just mean wide FoV then just set a wide FoV… but for true fisheye you somehow have to get edges to bend. So standard triangle rasterization won’t work.

1 Like

I meanwhile googled as well and found some pages which are about fisheye perspective like this one (Shader Library) Fish Eye, Dome and Barrel Distortion GLSL Post Processing Filters | Geeks3D So I probably get a standard shader from jme and take that as a base to bring in the proposed shader logic from this link.

1 Like

You can find some good fish eye shaders on Shadertoy. Maybe that’s a good starting point.

1 Like

Hah managed it :smiley:

MaterialDef Toon {

    MaterialParameters {
        Int NumSamples
        Int NumSamplesDepth
        Texture2D Texture
        Color Color        

    Technique {
        VertexShader GLSL100:   MatDefs/Post/Fisheye.vert
        FragmentShader GLSL100: MatDefs/Post/Fisheye.frag

        WorldParameters {

        Defines {
            RESOLVE_MS : NumSamples


#import "Common/ShaderLib/GLSLCompat.glsllib"

attribute vec4 inPosition;
varying vec4 Vertex_UV;
uniform mat4 gxl3d_ModelViewProjectionMatrix;
attribute vec2 inTexCoord;

void main()
    vec2 pos = inPosition.xy * 2.0 - 1.0;
    gl_Position = vec4(pos, 0.0, 1.0);    
    Vertex_UV = vec4(inTexCoord, 0.0, 0.0);


#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/ShaderLib/MultiSample.glsllib"

uniform sampler2D tex0;
varying vec4 Vertex_UV;
const float PI = 3.1415926535;

void main() {
  float aperture = 178.0;
  float apertureHalf = 0.5 * aperture * (PI / 180.0);
  float maxFactor = sin(apertureHalf);
  vec2 uv;
  vec2 xy = 2.0 * Vertex_UV.xy - 1.0;
  float d = length(xy);
  if (d < (2.0-maxFactor)) {
    d = length(xy * maxFactor);
    float z = sqrt(1.0 - d * d);
    float r = atan(d, z) / PI;
    float phi = atan(xy.y, xy.x);
    uv.x = r * cos(phi) + 0.5;
    uv.y = r * sin(phi) + 0.5;
  }  else  {
    uv = Vertex_UV.xy;
  vec4 c = texture2D(tex0, uv);
  gl_FragColor = c;

And the result looks like this…


So basically, your edges are still straight but all of your ‘triangles’ are small and so it doesn’t matter.

Edit: or is this a full screen effect? (Starting to think it is now that I’m re-reading.)

Supposed to be a full screen effect. It’s a filter. Honestly I didn’t jet study the frag part :slight_smile: I just made an existing shader post filter working with jme. Struggled a bit with the import part like the vert part until I had it. I figured that UV is our inTexCoord which is a vec2. I guess I can clean it up a bit and just work with the vec2 in the frag filter as well (well the .xy does that), so go over a vec4 was just the quick trial :smiley:

Ok, so it’s only a 2D effect and not a 3D fish eye.

2D is waaaay simpler, yeah. “Back in the day”, we’d have done it with a lookup table. Modern shaders can do it plenty fast now. Just a spherical reprojection in the end.

Real 3D fish eye is actually “really hard” ™.

Yeah I will look if I find a real fish eye on shader toy. But it’s a start and more over it’s a start into this shader world I avoided for so long.


Reminds me of then I wrote my first shader recently after years of working with jMonkey in order to get a day/night cycle working. After that, I ended up using @sgold’s SkyControl library, scrapping all that work.
Hey, it was informative, though!

1 Like