I’m quite new to shaders and I’m having some trouble implementing this Radial Undistortion example from GPU Gems. The shader uses the lens distortion coefficients generated during camera calibration to correct geometric distortion in real-time.
I’m working from the Fisheye example, which distorts a scene camera’s view to simulate a fisheye lens.
The shader that I have written is as follows:
Shader "Custom/CameraUndistort" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord.xy;
return o;
}
float4 frag(v2f i) : COLOR
{
float2 coords = i.uv;
float4 pos = i.pos;
// known constants for the particular lens and sensor
float f = 368.28488; // focal length
float ox = 147.54834; // principal point, x axis
float oy = 126.01673; // principal point, y axis
float k1 = 0.4142; // constant for radial distortion correction
float k2 = 0.40348;
float2 xy = (coords - float2(ox, oy))/float2(f,f);
float r = sqrt(dot(xy,xy));
float r2 = r * r;
float r4 = r2 * r2;
float coeff = (k1 * r2 + k2 * r4);
// add the calculated offsets to the current texture coordinates
xy = ((xy + xy * coeff.xx) * f.xx) + float2(ox, oy);
// look up the texture at the corrected coordinates and output the color
return texRECT(_MainTex, xy);
}
ENDCG
}
}
Fallback off
}
And my associated script attached to the camera is as follows:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent (typeof(Camera))]
[AddComponentMenu ("Image Effects/CameraUndistort")]
public class CameraUndistort : PostEffectsBase {
public Shader CameraUndistortShader = null;
public Material CameraUndistortMaterial = null;
bool CheckResources (){
CheckSupport (false);
CameraUndistortMaterial = CheckShaderAndCreateMaterial(CameraUndistortShader,CameraUndistortMaterial);
if(!isSupported)
ReportAutoDisable ();
return isSupported;
}
void OnRenderImage (RenderTexture source, RenderTexture destination){
if(CheckResources()==false) {
Graphics.Blit (source, destination);
return;
}
Graphics.Blit (source, destination, CameraUndistortMaterial);
}
}
At the moment the result I get is my scene camera showing completely white. I’ve tried a number of alterations to both the shader and the script, but I’m obviously doing some things wrong. I may not be connecting the shader output with the material on the script or something like that. Any help would be much appreciated.