Compensate for chromatic aberration in the Oculus Rift combiner
authorMikko Rasa <tdb@tdb.fi>
Fri, 13 Sep 2013 13:26:44 +0000 (16:26 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 13 Sep 2013 13:26:44 +0000 (16:26 +0300)
source/oculusriftcombiner.cpp
source/oculusriftcombiner.h

index 771f3b82a3cd7df48f48854b10e7b786c931bc72..6d5ebf123ea2812e115c7ee29562c5e49dbf2f39 100644 (file)
@@ -21,21 +21,23 @@ const char vs_source[] =
 const char fs_source[] =
        "uniform sampler2D texture;\n"
        "uniform vec4 distortion;\n"
+       "uniform vec4 chromatic;\n"
        "uniform vec2 eye_center;\n"
        "uniform vec3 scale;\n"
        "varying vec2 texcoord;\n"
-       "vec2 distort(vec2 coord)\n"
-       "{\n"
-       "       float r_sq = dot(coord, coord);\n"
-       "       return coord*dot(distortion, vec4(1.0, r_sq, r_sq*r_sq, r_sq*r_sq*r_sq));\n"
-       "}\n"
        "void main()\n"
        "{\n"
-       "       vec2 dtc = (distort(texcoord)-eye_center)/(scale.xy*scale.z)+0.5;\n"
+       "       float r_sq = dot(texcoord, texcoord);\n"
+       "       float f = dot(distortion, vec4(1.0, r_sq, r_sq*r_sq, r_sq*r_sq*r_sq));\n"
+       "       vec2 dtc = (texcoord*f-eye_center)/(scale.xy*scale.z)+0.5;\n"
        "       if(dtc.x<0.0 || dtc.y<0.0 || dtc.x>1.0 || dtc.y>1.0)\n"
        "               gl_FragColor = vec4(0.0);\n"
        "       else\n"
-       "               gl_FragColor = texture2D(texture, dtc);\n"
+       "       {\n"
+       "               vec2 red_dtc = (texcoord*f*(chromatic[0]+chromatic[1]*r_sq)-eye_center)/(scale.xy*scale.z)+0.5;\n"
+       "               vec2 blue_dtc = (texcoord*f*(chromatic[2]+chromatic[3]*r_sq)-eye_center)/(scale.xy*scale.z)+0.5;\n"
+       "               gl_FragColor = vec4(texture2D(texture, red_dtc).r, texture2D(texture, dtc).g, texture2D(texture, blue_dtc).b, 1.0);\n"
+       "       }\n"
        "}\n";
 
 }
@@ -59,6 +61,11 @@ OculusRiftCombiner::OculusRiftCombiner():
        right_shdata.uniform("texture", 0);
        right_shdata.uniform("offset", 0.5f);
 
+       chromatic[0] = 1.0f;
+       chromatic[1] = 0.0f;
+       chromatic[2] = 1.0f;
+       chromatic[3] = 0.0f;
+
        // This will also call update_parameters
        set_distortion(1.0f, 0.22f, 0.24f);
 
@@ -99,6 +106,22 @@ void OculusRiftCombiner::set_distortion(float d0, float d1, float d2, float d3)
        update_parameters();
 }
 
+void OculusRiftCombiner::set_red_aberration(float c0, float c1)
+{
+       chromatic[0] = c0;
+       chromatic[1] = c1;
+
+       update_parameters();
+}
+
+void OculusRiftCombiner::set_blue_aberration(float c2, float c3)
+{
+       chromatic[2] = c2;
+       chromatic[3] = c3;
+
+       update_parameters();
+}
+
 void OculusRiftCombiner::set_fill_factor(float f)
 {
        fill_factor = f;
@@ -108,7 +131,9 @@ void OculusRiftCombiner::set_fill_factor(float f)
 void OculusRiftCombiner::update_parameters()
 {
        left_shdata.uniform4("distortion", distortion);
+       left_shdata.uniform4("chromatic", chromatic);
        right_shdata.uniform4("distortion", distortion);
+       right_shdata.uniform4("chromatic", chromatic);
 
        // Set lens center positions, in output texture coordinates
        left_shdata.uniform("lens_center", 1.0f-lens_separation, 0.5);
index a204c3eff766b25085095cdc4e6020f99423029b..afb5573453b99345edf9900b7c245dc03215122f 100644 (file)
@@ -24,6 +24,7 @@ private:
        float lens_separation;
        float eye_separation;
        float distortion[4];
+       float chromatic[4];
        float fill_factor;
 
 public:
@@ -33,6 +34,8 @@ public:
        void set_lens_separation(float);
        void set_eye_separation(float);
        void set_distortion(float = 1.0f, float = 0.0f, float = 0.0f, float = 0.0f);
+       void set_red_aberration(float = 1.0f, float = 0.0f);
+       void set_blue_aberration(float = 1.0f, float = 0.0f);
        void set_fill_factor(float);
 private:
        void update_parameters();